DZone
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
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

The Latest Coding Topics

article thumbnail
Running JUnit tests in Parallel with Maven
A little-known but very useful feature slipped into JUnit 4 and recent versions of the Maven Surefire Plugin: support for parallel testing.
July 7, 2010
by John Ferguson Smart
· 57,154 Views · 1 Like
article thumbnail
Refactoring into Scala Type Classes
A couple of weeks back I wrote about type class implementation in Scala using implicits. Type classes allow you to model orthogonal concerns of an abstraction without hardwiring it within the abstraction itself. This takes the bloat away from the core abstraction implementation into separate independent class structures. Very recently I refactored Akka actor serialization and gained some real insights into the benefits of using type classes. This post is a field report of the same. Inheritance and traits looked good .. .. but only initially. Myself and Jonas Boner had some cool discussions on serializable actors where the design we came up with looked as follows .. trait SerializableActor extends Actor trait StatelessSerializableActor extends SerializableActor trait StatefulSerializerSerializableActor extends SerializableActor { val serializer: Serializer //.. } trait StatefulWrappedSerializableActor extends SerializableActor { def toBinary: Array[Byte] def fromBinary(bytes: Array[Byte]) } // .. and so on All these traits make the concerns of serializability just too coupled with the core Actor implementation. And with various forms of serializable actors, clearly we were running out of class names. One of the wisdoms that the GoF Patterns book taught us was that when you struggle naming your classes using inheritance, you're definitely doing it wrong! Look out for other ways that separate the concerns more meaningfully. With Type Classes .. We took the serialization stuff out of the core Actor abstraction into a separate type class. /** * Type class definition for Actor Serialization */ trait FromBinary[T <: Actor] { def fromBinary(bytes: Array[Byte], act: T): T } trait ToBinary[T <: Actor] { def toBinary(t: T): Array[Byte] } // client needs to implement Format[] for the respective actor trait Format[T <: Actor] extends FromBinary[T] with ToBinary[T] We define 2 type classes FromBinary[T <: Actor] and ToBinary[T <: Actor] that the client needs to implement in order to make actors serializable. And we package them together as yet another trait Format[T <: Actor] that combines both of them. Next we define a separate module that publishes APIs to serialize actors that use these type class implementations .. /** * Module for actor serialization */ object ActorSerialization { def fromBinary[T <: Actor](bytes: Array[Byte]) (implicit format: Format[T]): ActorRef = //.. def toBinary[T <: Actor](a: ActorRef) (implicit format: Format[T]): Array[Byte] = //.. //.. implementation } Note that these type classes are passed as implicit arguments that the Scala compiler will pick up from the surrounding lexical scope. Here's a sample test case which implements the above strategy .. A sample actor with encapsulated state. Note that we no longer have any incidental complexity of my actor having to inherit from any specialized Actor class .. class MyActor extends Actor { var count = 0 def receive = { case "hello" => count = count + 1 self.reply("world " + count) } } and the client implements the type class for protocol buffer based serialization and package it as a Scala module .. object BinaryFormatMyActor { implicit object MyActorFormat extends Format[MyActor] { def fromBinary(bytes: Array[Byte], act: MyActor) = { val p = Serializer.Protobuf .fromBinary(bytes, Some(classOf[ProtobufProtocol.Counter])) .asInstanceOf[ProtobufProtocol.Counter] act.count = p.getCount act } def toBinary(ac: MyActor) = ProtobufProtocol.Counter.newBuilder.setCount(ac.count).build.toByteArray } } We have a test snippet that uses the above type class implementation .. import ActorSerialization._ import BinaryFormatMyActor._ val actor1 = actorOf[MyActor].start (actor1 !! "hello").getOrElse("_") should equal("world 1") (actor1 !! "hello").getOrElse("_") should equal("world 2") val bytes = toBinary(actor1) val actor2 = fromBinary(bytes) actor2.start (actor2 !! "hello").getOrElse("_") should equal("world 3") Note that the state is correctly serialized by toBinary and then subsequently de-serialized to get the updated value of the Actor state. This refactoring has made the core actor implementation much cleaner moving away the concerns of serialization to a separate abstraction. The client code also becomes cleaner in the sense that the client actor definition does not include details of how the actor state is being serialized. Scala's power of implicit arguments and executable modules made this type class based implementation possible. From http://debasishg.blogspot.com/2010/07/refactoring-into-scala-type-classes.html
July 7, 2010
by Debasish Ghosh
· 7,918 Views
article thumbnail
Spring Framework Architecture
the spring framework is a layered architecture which consists of several modules. all modules are built on the top of its core container. these modules provide everything that a developer may need for use in the enterprise application development. he is always free to choose what features he needs and eliminate the modules which are of no use. it's modular architecture enables integration with other frameworks without much hassle. the core module: provides the dependency injection (di) feature which is the basic concept of the spring framework. this module contains the beanfactory, an implementation of factory pattern which creates the bean as per the configurations provided by the developer in an xml file. aop module: the aspect oriented programming module allows developers to define method-interceptors and point cuts to keep the concerns apart. it is configured at run time so the compilation step is skipped. it aims at declarative transaction management which is easier to maintain. dao module: this provides an abstraction layer to the low level task of creating a connection, releasing it etc. it also maintains a hierarchy of meaningful exceptions rather than throwing complicated error codes from specific database vendors. it uses aop to manage transactions. transactions can also be managed programmatically. orm module: spring doesn’t provides its own orm implementation but offers integrations with popular object relational mapping tools like hibernate, ibatis sql maps, oracle toplink and jpa etc. jee module: it also provides support for jmx, jca, ejb and jms etc. in lots of cases, jca (java ee connection api) is much like jdbc, except where jdbc is focused on database jca focus on connecting to legacy systems. web module: spring comes with mvc framework which eases the task of developing web applications. it also integrates well with the most popular mvc frameworks like struts, tapestry, jsf, wicket etc. from http://himanshugpt.wordpress.com/2010/07/05/262/
July 6, 2010
by Himanshu Gupta
· 118,392 Views · 10 Likes
article thumbnail
Pragmatic Look at Method Injection
Intent Allows container to inject methods instead of objects and provides dynamic sub classing. Also Known As Method decoration (or AOP injection) Motivation Sometimes it happens that we need to have a factory method in our class which creates a new object each time we access the class. For example, we might have a RequestProcessor which has a method called process which takes a request as an input and returns a response as an output. But, before the response is generated, request needs to be validated and then passed to a service class which will process the request and returns the response. public class RequestProcessor implements Processor { private Service service; public Response process(Request request) { Validator validator = getNewValidatorInstance(); List errorMessages = validator.validate(request); if (!errorMessages.isEmpty()) { throw new RuntimeException("Validation Error"); } Response response = service.makeServiceCall(request); return response; } protected ValidatorImpl getNewValidatorInstance() { return new ValidatorImpl(); } } As can be seen in the above code snippet, we are creating a new ValidatorImpl instance each time process method is called. RequestProcessor requires a new instance each time because Validator might have some state which should be different for each request(for example a list of error messages). RequestProcessor bean is managed by dependency injection container like spring where as Validator is being instantiated within the RequestProcessor. This solution looks like ideal but it has few shortcomings : RequestProcessor is tightly coupled to the Validator implementation details. If Validator had any constructor dependencies, then RequestProcessor need to know them also. For example, if Validator has a dependency on some Helper class which is injected in Validator constructor then RequestProcessor needs to know about helper also. There is also another approach that you can take in which container will manage the Validator bean(prototype) and you can make bean aware of the container by implementing ApplicationContextAware interface. public class RequestProcessor implements Processor,ApplicationContextAware { private Service service; private ApplicationContext applicationContext; public Response process(Request request) { Validator validator = getNewValidatorInstance(); List errorMessages = validator.validate(request); if (!errorMessages.isEmpty()) { throw new RuntimeException("Validation Error"); } Response response = getService().makeServiceCall(request); return response; } protected Validator getNewValidatorInstance() { return (Validator)applicationContext.getBean("validator"); } public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } public void setService(Service service) { this.service = service; } public Service getService() { return service; } } This approach also has its drawback as the application business logic is now coupled with Spring framework. Method injection provides a better way to handle such cases. The key to Method injection is that the method can be overridden to return the another bean in the container.In Spring method injection uses CGLIB library to dynamically override a class. Applicability Use Method injection when you want to avoid container dependency as we have seen in the second approach, in which you have to inject a non singleton bean inside a singleton bean. you want to avoid subclassing. For example, suppose that RequestProcessor is processing two types of response and depending upon the the type of report , we use different validators. So, we can have subclass RequestProcessor and have Report1RequestProcessor which just provides the Validator required for Report1. public class Report1RequestProcessor extends RequestProcessor { @Override protected Validator getNewValidatorInstance() { return new ValidatorImpl(); } } public abstract class RequestProcessor implements Processor { private Service service; public Response process(Request request) { Validator validator = getNewValidatorInstance(); List errorMessages = validator.validate(request); if (!errorMessages.isEmpty()) { throw new RuntimeException("Validation Error"); } Response response = getService().makeServiceCall(request); return response; } protected abstract Validator getNewValidatorInstance(); public void setService(Service service) { this.service = service; } public Service getService() { return service; } } Implementation Method injection provides a cleaner solution. Dependency Injection container like Spring will override getNewValidatorInstance() method and your business code will be independent of both the spring framework infrastructure code as well as Concrete implementation of Validator interface. So, you can code to interface. public abstract class RequestProcessor implements Processor { private Service service; public Response process(Request request) { Validator validator = getNewValidatorInstance(); List errorMessages = validator.validate(request); if (!errorMessages.isEmpty()) { throw new RuntimeException("Validation Error"); } Response response = getService().makeServiceCall(request); return response; } protected abstract Validator getNewValidatorInstance(); public void setService(Service service) { this.service = service; } public Service getService() { return service; } } The method requires a following signature [abstract] methodName(no-arguments); If the class does not provide implementation as in our class RequestProcessor, Spring dynamically generates a subclass which implements the method otherwise it overrides the method. application-context.xml will look like this This is how method injection can be used in our applications. Consequences Method injection has following benefits: 1) Provides dynamic subclassing 2) Getting rid of container infrastructure code in scenarios where Singleton bean needs to have non singleton or prototype bean. Method injection has following Liabilities : 1) Unit testing - Unit testing will become difficult as we have to test the abstract class. You can avoid this by making the method which provides you the instance as non-abstract but that method implementation will be redundant as container will always override it. 2) Adds magic in your code - Anyone not familiar with method injection will have hard time finding out how the code is working. So, it might make your code hard to understand.
July 5, 2010
by Shekhar Gulati
· 34,741 Views · 2 Likes
article thumbnail
Practical PHP Patterns: Metadata Mapping
The intent of the Metadata Mapping pattern is to express implementation details, related a particular domain and Domain Model, as metadata of a general purpose library. In the sense intended here, metadata is related to the persistence operations (transferring objects back and forth from a database). These metadata is usually fed to a general purpose object-relational mapper. Technically the term metadata is plural (of metadatum, data about data), but it is commonly used as an uncountable noun. Why expressing metadata Object-relational mapping is a difficult task to automate, prone to lots of potential bugs and undefined behaviors; expressing the domain-related peculiarities as metadata means that you are able to code only one ORM, and not have to repeat the same work in many custom Data Mappers, which are very boring to write and can't be transported out a specific application. Custom Data Mappers were a cleaner solution for Domain Models with regard to employing Active Records, and they are advocated for example in Zend Framework books like Keith's Pope one. They are finally becoming obsolete thanks to the power of a declarative approach like this pattern, which tools like Doctrine 2 are based on. Historicacally, Hibernate from JBoss was the first Data Mapper implemented as a generic ORM (it is a Java product). Doctrine 2 is the most famous PHP implementation, and it is in beta at the time of this writing. The metadata we'd like to tell to an ORM are for example: which classes should be persisted at all. Optional names for the tables (it can use the class names.) Which fields form the primary key. The types of the different columns, particularly important in a loosely typed language like PHP. Which collaborators have to be persisted and via what means: foreign keys and additional association tables. The metadata should usually not consist of code: non-standard behavior shouldn't be contained in them, as in general all the behavior like ineritance strategies and conversion of relationships is extracted in the generic ORM. Thus there are different formats we can use in place of PHP code: XML, annotations, YAML, INI... Different approaches There are two approaches to Metadata Mapping pattern, described by Fowler in his original book. The first one is code generation: the metadata is processed to generate the source code of the mapping classes, for example a Data Mapper for every entity or aggregate root of your model (one for User, one for BlogPost, and so on). The ORM would theoretically not be necessary in production if the generation is complete enough. Doctrine 1 used this approach in part, but it generated also the PHP code of the domain model itself from the Yaml mapping, as subclasses of Doctrine_Record. Still, Doctrine 1 was necessary to instantiate those classes and the solution wasn't so clean. Doctrine 2 is very different in architecture and goals. The second approach is called reflective program, and consists in interpreting the mapping at runtime in the ORM's code, to open up correctly the objects via reflection (or a standard interface) and putting them in the database. The converse can happen: objects can be recreated from the union of metadata and database tables. How it is used The reflective solution is the common one nowadays, and Doctrine 2 borrows it from Hibernate in its own design. Reflection is used to access the private fields to persist. Some critics point out speed problems of this technique, but keep in mind that your ORM is communicating with an external process or database machine at the same time of using reflection: it probably won't count much in the benchmark. Doctrine 2 however takes optimization seriously to the point that metadata internal classes (accessed very often) present an Api with public properties instead of methods to avoid every overhead in a crucial part (hydration of objects with data retrieved from the database). An advantage of generated code is that it would be easier to debug, but it is usually a pain to maintain: every time you evolve or refactor a domain class you have to regenerate the Mapper classes. You can't customize this code either, because you would lost your changes at the regeneration time. Advantages and (few) disadvantages Of course we lose some expressiveness by specifying metadata instead of a programmatical behavior like the source code of a custom Data Mapper. But we gain very much: a fully tested ORM, like Doctrine 2 in the PHP case, with only some lines of added metadata to keep in sync with the rest of the code base. Declarative approaches trading off completeness of functionalities (the absent ones are not used very often anyway) for developers time. But there are other advantages, such as the generation (and migration) of the database schema based on the metadata, and also of the proxy classes. Ideally, the metadata mapping is the only point of strong coupling of your Domain Model with an external adapter, the ORM. It is of course part of the infrastructure, so keep it under version control along with the code! Adding and removing fields or relationships, changing keys or refactoring is much easier because you do it declaratively instead of refactoring a specific mapper class. Note that automated refactoring tools are not to be trusted here: for example they usually ignore the mapping when you change a field name. So grep is your best ally. Examples The sample code of this article will present the different ways of specifying metadata for Doctrine 2, the most high-tech PHP ORM. The performance of the different methods are equivalent, since the metadata are read only one time into native PHP objects and then cached. Metadata is a vast subject since all the different persistence implementations have to be driven by it, but we will look more at the types of metadata specification we can use instead of all the different metadata instances, which are best described in conjunction with the single features (for example, the inheritance patterns articles contain the description of the metadata related to subclassing.) The simplest way to express metadata mapping in Doctrine 2 is via annotations, embedded in the docblocks and ignored from anything but the ORM: Don't be alarmed by the size: this mapping does much more than the annotations example's one. A third way to specify metadata is via YAML, a format widely used in symfony-related software: --- # Doctrine.Tests.ORM.Mapping.User.dcm.yml Doctrine\Tests\ORM\Mapping\User: type: entity table: cms_users id: id: type: integer generator: strategy: AUTO fields: name: type: string length: 50 oneToOne: address: targetEntity: Address joinColumn: name: address_id referencedColumnName: id oneToMany: phonenumbers: targetEntity: Phonenumber mappedBy: user cascade: cascadePersist manyToMany: groups: targetEntity: Group joinTable: name: cms_users_groups joinColumns: user_id: referencedColumnName: id inverseJoinColumns: group_id: referencedColumnName: id lifecycleCallbacks: prePersist: [ doStuffOnPrePersist, doOtherStuffOnPrePersistToo ] postPersist: [ doStuffOnPostPersist ]
July 5, 2010
by Giorgio Sironi
· 3,962 Views
article thumbnail
Are You A Starter, A Finisher Or An Implementer?
There are three parts to every project, starting, finishing and everything in between. Two parts of the process are very difficult to complete, starting and finishing. This is not a tutorial on project management, as much as it is a general guide for people involved in a project. For example, lots of people have ideas. Ideas are easy because they require very little risk. But, what happens after the idea? You are supposed to start the project. However, most people stop with the idea because they “don’t have time” or even “I wouldn’t know where to begin”. Kat French explains how she does her best creative work: The super-secret, hush-hush, “I could tell you, but then I’d have to kill you” secret of how I do my best creative work. Ready? It’s called “starting.” The recipe is.. there is no recipe. This isn’t science. It’s more like alchemy. There are ingredients. Usually those ingredients have certain effects. When you put them all together and apply heat…”results may vary,” Starting does not mean that everything will go well or that you will be successful. Starting just means that you took the initiative to start, and that probably puts you ahead of the majority of workers out there. In order for a project to be successful, you have to start at some point. Most people are not good starters, they need some core foundation or baseline to start with. Some people also need the structure of a formal project management methodology or a detailed task list. The term “self-starter” has been abused by the whole recruitment/HR industry to become someone who can do their own work without significant prodding. What do you call someone who can take an idea and start a project? Some people may throw the title “entrepreneur” at that person, but it also has other meanings. The key is that this person can start something. Are you that person? One problem is that the starter may not be very good at filling in the various details of the project or finishing the project. Starters may be excited by the novelty of a project, but once you get mired in details, the novelty has worn off. By the time you are trying to finish the project, the starter is probably bored or even hates his job. Given that we know that no project is ever really done, you might be able to keep the starter happy by having them begin work on the next phase of the project or a significant new feature. At the other end of the project is completion. Starters typically do not fare well as a finisher of a project. As an example, look at the typical software development project. At the beginning of the project, there is a lot of technology research and foundation or framework code that needs to be completed. Starters love that work. At the end of a project, most of the work is in validating and correcting defects, and working with other departments to ensure deployment goes smoothly. A finisher is the person that works well juggling multiple tasks, fixing defects and managing processes to completion. Obviously, this is a very different person than the starter. The finisher loves a detailed task list as it gives them a goal. If they complete all of these tasks, it is likely that the project has reached its conclusion and the application has been deployed. However, you cannot always be really finishing a project, so how do you keep the finisher happy? Similar to the starter, you can have the finisher move from one project or feature to another. They are a nice complement to the starter in terms of the tasks to be completed. Are you a finisher? But how do you have one project look like several? In project management, a large project is broken into phases, which are really just smaller projects. If you do not have a really large project, you can create smaller projects by looking for milestones in your project. Agile methodologies take this concept to the extreme by ensuring that there is a fixed time for each iteration. In some cases, an iteration could be long enough to implement one feature. So, each feature in your product could become an iteration or a small project. So, we have talked about starting and finishing, but what about the stuff in between? Someone needs to fill in the details. I started by calling this person a filler, but that does not sound like a good name for someone. So, I will call this person an implementer. This person takes the basic infrastructure and puts the application features on top of it. They create the web forms and the code to save the data, using the frameworks provided by the starter. Most people fall into this category because it has the broadest spectrum of work. Each web page or feature may look like a new project for them. They may not require a detailed task list, depending upon experience, but they look at the requirements and fill in the details. Are you an implementer? Because most projects are full of details, the implementer has plenty of work to do. They can be moved from project to project filling in the gaps that the starter and finisher do not complete. Given that there are so many details in projects, this is where a project manager will spend a bulk of their time, managing the implementers. Implementers will also be the most diverse group of people, so management of these people could be a daunting task as well. Of course, the next question from people would be who is most valuable. For that question, I give you a quote from a Seth Godin post about linchpins: A newspaper asked me the following, which practically set my hair on fire: What inherent traits would make it easier for someone to becoming a linchpin? Surely not everyone can be a linchpin? Why not? Each of these types of people are important. What good is a starter if there is nobody there to finish? If you have a finisher, who starts the project in the right direction? Once the project is started someone needs to fill in the details, and that is not the starter or the finisher. There are some of those rare people that can take a project from start to finish, and there are others that overlap into two of the three groups. But you should be honest with yourself. What are you good at? Starting? Finishing? The stuff in between? From http://regulargeek.com/2010/06/24/are-you-a-starter-a-finisher-or-an-implementer
July 5, 2010
by Robert Diana
· 18,275 Views
article thumbnail
How to Automatically Recover Tomcat From Crashes
Tomcat occasionally crashes if you do frequent hot-deploys or if you are running it on a machine with low memory. Every time tomcat crashes someone has to manually restart it, so I wrote a script which automatically detects that tomcat has crashed and restarts it. Here’s the pseudo logic: every few minutes { check tomcat status; if (status is "not running") { start tomcat; } } every few minutes { check tomcat status; if (status is "not running") { start tomcat; } } Here’s a shell script to implement the above logic. It assumes that you are running on a unix/linux system and have /etc/init.d/tomcat* script setup to manage tomcat. Adjust the path to “/etc/init.d/tomcat” in the script below to reflect the correct path on your computer. Sometimes it is called /etc/init.d/tomcat5 or /etc/init.d/tomcat6 depending on your tomcat version. Also make sure that the message “Tomcat Servlet Container is not running.” matches with the message that you get when you run the script when tomcat is stopped. #! /bin/sh SERVICE=/etc/init.d/tomcat STOPPED_MESSAGE="Tomcat Servlet Container is not running." if [ "`$SERVICE status`" == "$STOPPED_MESSAGE"]; then { $SERVICE start } fi #! /bin/sh SERVICE=/etc/init.d/tomcat STOPPED_MESSAGE="Tomcat Servlet Container is not running." if [ "`$SERVICE status`" == "$STOPPED_MESSAGE"]; then { $SERVICE start } fi To run the script every 10 minutes: 1. Save the above script to “/root/bin/recover-tomcat.sh”. 2. Add execute permission: chmod +x /root/bin/recover-tomcat.sh chmod +x /root/bin/recover-tomcat.sh 3. Add this to root’s crontab, type the following as root: crontab -e crontab -e 4. Add the following lines to the crontab: # monitor tomcat every 10 minutes */10 * * * * /root/bin/recover-tomcat.sh # monitor tomcat every 10 minutes */10 * * * * /root/bin/recover-tomcat.sh What if I don’t have /etc/init.d/tomcat* script on my computer? Tomcat creates a pid file, typically in the TOMCAT_HOME/bin directory. This file contains the process id of the tomcat process running on the machine. The pseudo logic in that case would be: if (the PID file does not exist) { // conclude that tomcat is not running start tomcat } else { read the process id from the PID file if (no process that id is running) { // conclude that tomcat has crashed start tomcat } } if (the PID file does not exist) { // conclude that tomcat is not running start tomcat } else { read the process id from the PID file if (no process that id is running) { // conclude that tomcat has crashed start tomcat } } You can implement the above logic as follows. The following is experimental and is merely a suggested way, test it on your computer before using it. # adjust this to reflect tomcat home on your computer TOMCAT_HOME=/opt/tomcat5 if [ -f $TOMCAT_HOME/bin/tomcat.pid ] then echo "PID file exists" pid="`cat $TOMCAT_HOME/bin/tomcat.pid`" if [ "X`ps -p $pid | awk '{print $1}' | tail -1`" = "X"] then echo "Tomcat is running" else echo "Tomcat had crashed" $TOMCAT_HOME/bin/startup.sh fi else echo "PID file does not exist. Restarting..." $TOMCAT_HOME/bin/startup.sh fi # adjust this to reflect tomcat home on your computer TOMCAT_HOME=/opt/tomcat5 if [ -f $TOMCAT_HOME/bin/tomcat.pid ] then echo "PID file exists" pid="`cat $TOMCAT_HOME/bin/tomcat.pid`" if [ "X`ps -p $pid | awk '{print $1}' | tail -1`" = "X"] then echo "Tomcat is running" else echo "Tomcat had crashed" $TOMCAT_HOME/bin/startup.sh fi else echo "PID file does not exist. Restarting..." $TOMCAT_HOME/bin/startup.sh fi Why would tomcat crash? The most common reason is low memory. For example, if you have allocated 1024MB of max memory to tomcat and enough memory is not available on that machine. Other reasons may involve repeated hot-deploys causing memory leaks, rare JVM bugs causing the JVM to crash. From http://www.vineetmanohar.com/2010/06/howto-auto-recover-tomcat-crashes
June 28, 2010
by Vineet Manohar
· 29,818 Views
article thumbnail
16 Tips for Securing Your Admin Page
So you've finished that shiny new website and you want make sure that you and your buddies are in control. Besides the obvious things such as SSL and logging all access, there are a fewest practices for authentication/access that developers recommend. Here are some of the recommendations: Require separate login pages for users and admin using the same DB table. This will prevent XSRF and session-stealing, plus the attacker won't be able to access to admin areas) [Thief Master] Use complex passwords for admin accounts. For example, "uvula{:&:>iuJ", not "12345". Of course, you have to remember it. :) [Developer Art] Introduce an artificial pause between each admin password attempt to prevent brute force attacks. [Lo'oris] Blocking users IP after a number of failed admin login attempts or requiring a CAPTCHA after a failed login (but not the first one, because that's really annoying) will also stop brute force attacks. [Thief Master] If the admin section is in a separate subdirectory, you should consider also adding webserver native authentication to that area (e.g. via .htaccess in Apache). Then an attacker would need both the subdirectory password and the user password. [Thief Master] Consider Second level authentication such as client certificates (e.g. x509 certs), smart cards, cardspace, etc. [JoeGeeky] Restrict access to the admin area. Only allow clients from trusted IPs/Domains. [JoeGeeky] Lock down IPrincipal & Principal-based authorization and make rights immutable and non-enumerable. Also make sure that all authorization assessments are based on the Principal. [JoeGeeky] Set up an email notification system that alerts admins when any rights are upgraded. This will help you catch an attacker that elevates his/her rights. [JoeGeeky] Consider fine-grained rights for admins. Typical Role-Based Security (RBS) approaches are not as safe because some roles will end up with more rights that they need. You should distribute rights based on the exact actions that a admin performs. This could cause a lot of overhead with more diverse admin-types, but it is safer because rights are issued more sparingly. [JoeGeeky] Restrict the creation of further admins and carefully control what admins can do to other admins. It's best to have a locked-down 'super-admin' client. [JoeGeeky] Consider Client Side SSL Certificates or RSA type keyfobs (electronic tokens) for added security. [Daniel Papasian] If you're using using cookies for authentication, use separate cookies for admin and normal pages. One way is to put the admin section on a different domain. [Daniel Papasian] One possibility, if it's practical, is to put the admin site on a private subnet instead of the internet. [John Hartsock] Re-issue auth/session tickets when moving between admin and normal usage contexts of the website. [Richard JP Le Guen] Require equally strong mechanisms (using the above techniques) for basic users so that admins aren't the only ones with highly-secure accounts. [Lo'oris] These tips were gathered in a question by UpTheCreek from StackOverflow.
June 21, 2010
by Mitch Pronschinske
· 9,172 Views
article thumbnail
NeoLoad 3.1 load tests Java Serialization
Neotys, a leader in easy-to-use, cost effective load testing tools for web applications today announced NeoLoad 3.1, the first test solution on the market to incorporate support for new push technologies such as Adobe RTMP or Ajax Push and now supports Java serialization. A new Java serialization module has been added to record and replay applications using the Java object serialization over HTTP. This module is fully compatible with the spring remote framework. New features Push Technologies module RTMP module Java Serialization module Advanced variabilization Alerts thresholds Customized reports > View all the new features. Free Trial Download the NeoLoad v3.1 demo (30-day free trial). More information http://www.neotys.com
June 18, 2010
by Christophe Marton
· 1,333 Views
article thumbnail
Builder Pattern Tutorial with Java Examples
Learn the Builder Design Pattern with easy Java source code examples as James Sugrue continues his design patterns tutorial series, Design Patterns Uncovered
June 15, 2010
by James Sugrue
· 92,380 Views · 14 Likes
article thumbnail
XML Processing and Validation Merging Together
Where does the border lie between validation and the processing itself? The question is if those should be even two separate procedures at all. Let's start with something simple like what the default values are. The most of the other Schema languages allow you to specify the default value. But when should the default value be used? What if some external resources are needed for the default value itself, like a database or a different value in the same document? Does the default value really have to be static? Yes that sounds familiar, it is processing already. XML Processing And what about the processing, didn't you ever need to be sure that the input is valid? And there is another common case, when you need to take actions during the processing based on the fact that some part of the document is valid or not. Sometimes you can't determine the variation of invalidness but you need to take some action based upon that. XDefinition merging processing and validation XDefinition is a schema language developed from the beginning with close respect to the natural readability by keeping the form of the XML data source. Designed to be understandable not only for programmers but also to analysts, system architects and all the other parties concerned with the project. This kind of approach leaves no space to misinterpret data description during it's exchange, starting from the architects to database specialists. XDefinition merges the validation and processing of the XML document as much as you need and what is more important if you need. In the example below we show the usage of an external method, based on the information obtained during the validation is called method. An External method could be any static method in the class supplied to the XDefinition processor through it's API. If you find this kind of approach interesting read the article about readability of the schema languages here on the Javalobby called XSD Schema is not the only way or try the Tutorial with examples. Resources: XDefinition guidepost
June 10, 2010
by Daniel Kec
· 8,924 Views
article thumbnail
State Pattern Tutorial with Java Examples
Learn the State Design Pattern with easy Java source code examples as James Sugrue continues his design patterns tutorial series, Design Patterns Uncovered
June 9, 2010
by James Sugrue
· 138,761 Views · 17 Likes
article thumbnail
Versioning Static Assets with UrlRewriteFilter
A few weeks ago, a co-worker sent me interesting email after talking with the Zoompf CEO at JSConf. One interesting tip mentioned was how we querystring the version on our scripts and css. Apparently this doesn't always cache the way we expected it would (some proxies will never cache an asset if it has a querystring). The recommendation is to rev the filename itself. This article explains how we implemented a "cache busting" system in our application with Maven and the UrlRewriteFilter. We originally used querystring in our implementation, but switched to filenames after reading Souders' recommendation. That part was figured out by my esteemed colleague Noah Paci. Our Requirements Make the URL include a version number for each static asset URL (JS, CSS and SWF) that serves to expire a client's cache of the asset. Insert the version number into the application so the version number can be included in the URL. Use a random version number when in development mode (based on running without a packaged war) so that developers will not need to clear their browser cache when making changes to static resources. The random version number should match the production version number formats which is currently: x.y-SNAPSHOT-revisionNumber When running in production, the version number/cachebust is computed once (when a Filter is initialized). In development, a new cachebust is computed on each request. In our app, we're using Maven, Spring and JSP, but the latter two don't really matter for the purposes of this discussion. Implementation Steps 1. First we added the buildnumber-maven-plugin to our project's pom.xml so the build number is calculated from SVN. org.codehaus.mojo buildnumber-maven-plugin 1.0-beta-4 validate create false false javasvn 2. Next we used the maven-war-plugin to add these values to our WAR's MANIFEST.MF file. maven-war-plugin 2.0.2 true ${project.version} ${buildNumber} ${timestamp} 3. Then we configured a Filter to read the values from this file on startup. If this file doesn't exist, a default version number of "1.0-SNAPSHOT-{random}" is used. Otherwise, the version is calculated as ${project.version}-${buildNumber}. private String buildNumber = null; ... @Override public void initFilterBean() throws ServletException { try { InputStream is = servletContext.getResourceAsStream("/META-INF/MANIFEST.MF"); if (is == null) { log.warn("META-INF/MANIFEST.MF not found."); } else { Manifest mf = new Manifest(); mf.read(is); Attributes atts = mf.getMainAttributes(); buildNumber = atts.getValue("Implementation-Version") + "-" + atts.getValue("Implementation-Build"); log.info("Application version set to: " + buildNumber); } } catch (IOException e) { log.error("I/O Exception reading manifest: " + e.getMessage()); } } ... // If there was a build number defined in the war, then use it for // the cache buster. Otherwise, assume we are in development mode // and use a random cache buster so developers don't have to clear // their browswer cache. requestVars.put("cachebust", buildNumber != null ? buildNumber : "1.0-SNAPSHOT-" + new Random().nextInt(100000)); 4. We then used the "cachebust" variable and appended it to static asset URLs as indicated below. The injection of /v/[CACHEBUSTINGSTRING]/(assets|compressed) eventually has to map back to the actual asset (that does not include the two first elements of the URI). The application must remove these two elements to map back to the actual asset. To do this, we use the UrlRewriteFilter. The UrlRewriteFilter is used (instead of Apache's mod_rewrite) so when developers run locally (using mvn jetty:run) they don't have to configure Apache. 5. In our application, "/compressed/" is mapped to wro4j's WroFilter. In order to get UrlRewriteFilter and WroFilter to work with this setup, the WroFilter has to accept FORWARD and REQUEST dispatchers. rewriteFilter /* WebResourceOptimizer /compressed/* FORWARD REQUEST Once this was configured, we added the following rules to our urlrewrite.xml to allow rewriting of any assets or compressed resource request back to its "correct" URL. ^/v/[0-9A-Za-z_.\-]+/assets/(.*)$ /assets/$1 ^/v/[0-9A-Za-z_.\-]+/compressed/(.*)$ /compressed/$1 /compressed/** /compressed/$1 Of course, you can also do this in Apache. This is what it might look like in your vhost.d file: RewriteEngine on RewriteLogLevel 0! RewriteLog /srv/log/apache22/app_rewrite_log RewriteRule ^/v/[.A-Za-z0-9_-]+/assets/(.*) /assets/$1 [PT] RewriteRule ^/v/[.A-Za-z0-9_-]+/compressed/(.*) /compressed/$1 [PT] Whether it's a good idea to implement this in Apache or using the UrlRewriteFilter is up for debate. If we're able to do this with the UrlRewriteFilter, the benefit of doing this at all in Apache is questionable, especially since it creates a duplicate of code. From http://raibledesigns.com/rd/entry/versioning_static_assets_with_urlrewritefilter
June 5, 2010
by Matt Raible
· 11,797 Views
article thumbnail
Handling Exceptions in Java Using Eclipse
What exactly is an exception? Exceptions are irregular or unusual events that happen in a method the program is calling which usually occurs at runtime. The method throws the Exception back to the caller to show that it is having a problem. If the programmer runs into this case, then they will need to extend an Exception from the Exception class that is already in the Java class library. In Eclipse, on the class declaration panel, the coder and request “constructors from superclass” and it will give the programmer constructors in a child Exception class that will accept error messages or the address of another Exception as a constructor parameter. When creating an Exception class, the programmer has to designate a kind of exception that must be caught or optionally caught. If you declare the Exception class to extend Exception as shown below, the compiler will insist that the method that is being thrown should also be in a caught in catch block. public class CodeName extends Exception { ……. } The compiler gives the programmer two choices when they call a method that throws an Exception that must be caught: 1. Add a try/catch in the code that is being call to catch the Exception 2. Pass the Exception back on to the caller If the programmer chooses option two then they can do this by adding a "throws" clause to end of the method declaration line. The compiler will generate the code to pass the Exception back to the caller at run-time. In the code below, the AnApplcation program is calling a Java Bean object's openFile() method, passing it the file name. The compiler will say to the openFile() method at compile time: "How do you want to handle the Exception?" The AJavaBean should realize there is nothing they can do in the openFile() method to fix the problem so the programmer should throw the Exception back to AnApplication. Eclipse can see the myProgram() in AnApplication is calling the openFile() method and when openFile() adds "throws FileNotFoundException" to its method declaration line, the compiler gives myProgram() method an error message asking the application method how it would like to handle the Exception. public class AnApplication { public void myProgram() { bean.openFile(filename); …… } } public class AJavaBean { public void openFile(String filename) throws FileNotFoundException { file.open(filename); //open() may throw FileNotFoundException …. } } If the programmer choose the first method then they can see below that all the code to process, open, and read are put into a try block. Once a method is called that might throw and Exception, the call has to be from within a try block because there is a chance of failure. If an Exception has been thrown by a method that is called in the try block shown below, the execution jumps out of the try block and into one of the catch blocks. The code that is left below that point in the try block is skipped as you can tell from the structure below. Execution will continue out the bottom of the catch block which branches to the bottom of the catch group if the catch block doesn’t stop the method processing by doing a return. Try/Catch example in Java: public void myProgram() { try { bean.openFile(fileName); // throws FileNotFoundException help.readFileContents(); // throws ReadException do.processFileData(); // throws ProcessException } catch(FileNotFoundException ex) { System.out.println(ex); // calls toString() on ex } catch(ReadException ex) { System.out.println(ex); // calls toString() on ex } catch(ProcessException ex) { System.out.println(ex); // calls toString() on ex } } } What happen if it was really vital that we close the file we open at the top of the try block? If you close it at the bottom of the try block, an exception is thrown and the execution will never get to the bottom of the try block. To guarantee the file gets closed, you would have to repeat the close() action in every one of the catch blocks which becomes repetitive coding. So you could remove all the close() and include a finally block at the bottom like shown below. After the try block has been entered, the finally code will be executed. The finally code will also be executed also if a catch block is entered, even if the catch does a return. public void myProgram() { try { bean.openFile(fileName); // throws FileNotFoundException help.readFileContents(); // throws ReadException do.processFileData(); // throws ProcessException } catch(FileNotFoundException ex) { System.out.println(ex); // calls toString() on ex } catch(ReadException ex) { System.out.println(ea); // calls toString() on ex } catch(ProcessException ex) { System.out.println(ex); // calls toString() on ex } finally { bean.close(filename); } } All the catch blocks print the Exception object’s toString() on the console as an error message. If you are not going to differentiate processing for different kinds of Exceptions, then you could use a “catch-all” block. Since all exception objects are type Exception then they will be directed into this catch block as shown below. Any unanticipated types of exception will be caught also. public void myProgram() { try { bean.openFile(fileName); // throws FileNotFoundException helper.readFileContents(); // throws ReadException do.processFileData(); // throws ProcessException } catch(Exception ex) { System.out.println(ex); // calls toString() on ex } finally { bean.close(filename); } }
June 4, 2010
by Joseph Randolph
· 24,803 Views
article thumbnail
System.ServiceModel.Syndication or how to read RSS feeds in .NET
Today, a lot of websites have their content provided in feeds that users can subscribe to. Feeds basically are a simplified version of the site content, providing text and media –only representation of the data published on the website. One of the most popular feed formats is RSS and it stands for Really Simple Syndication. It is XML-based and is used by the majority of websites that contain dynamically updated content, like blogs or news resources. Being XML based and having a well-defined structure, it is correct to think that it can be read as a regular XML document and this is absolutely true. However, there is System.Servicemodel.Syndication that can make the feed reading process a bit easier. So let’s look at a specific example. There is the DZone Link Feed, located here: http://feeds.dzone.com/dzone/frontpage?format=xml It’s an easy way to keep up with the upcoming interesting content, so I’d like to integrate this into my application. If I take a look at the source for the feed, I can see content similar to this: http://feeds.dzone.com/~r/dzone/frontpage/~3/wrVQN_7G8Hk/google_web_toolkit_blog_google_maps_api_for_gwt_1.html We are pleased to announce the Google Maps API for the Google Web Toolkit 1.1.0 release. The Google Maps API library provides a way to access the Google Maps API from a GWT project without having to write additional JavaScript code. frameworks java javascript web services Thu, 03 Jun 2010 18:54:42 GMT http://www.dzone.com/links/423703.html @thierry_lefort 2010-06-03T18:54:42Z We are pleased to announce the Google Maps API for the Google Web Toolkit 1.1.0 release. The Google Maps API library provides a way to access the Google Maps API from a GWT project without having to write additional JavaScript code.]]> 423703 2010-06-02T10:12:27Z 2010-06-03T18:54:42Z 6 0 90 0 http://www.dzone.com/links/images/thumbs/120x90/423703.jpg Thierry.Lefort http://www.dzone.com/links/images/avatars/252611.gif http://www.dzone.com/links/rss/google_web_toolkit_blog_google_maps_api_for_gwt_1.html As you can see here, an item is basically a feed entry that contains information about one content entity. Note that there are some site-specific tags that I am not covering here, but that are still readable via XmlDocument. An important note that has to be made here is that .NET (not using any third-party components) only supports RSS 2.0 feeds (I am not including Atom here). To get started, add a reference to System.ServiceModel and System.ServiceModel.Syndication. Now, in the class header, add the statement below: using System.ServiceModel.Syndication; Now you’re all set. Let’s try and read the feed above. To do this, I will need an instance of SyndicationFeed and XmlReader. Here is how the code looks like: SyndicationFeed feed = SyndicationFeed.Load(XmlReader.Create("http://feeds.dzone.com/dzone/frontpage")); This will read the actual feed. And since I mentioned that the feed is composed out of multiple items, all of them are stored in the Items collection. You can go through it via this: foreach (SyndicationItem item in feed.Items) { Debug.Print(item.Title.Text); } The code above will get the titles of each item included in the feed. A question that might arise is why do I have to call the Text property when Title should already be of type string. This is a wrong assumption, since Title in fact is of type TextSyndicationContent, therefore this means that it can contain HTML, XHTML or plain text. Therefore, converting it directly ToString() will not give correct results. For each of the items I can get the summary – a short representation of the published content: foreach (SyndicationItem item in feed.Items) { Debug.Print(item.Summary.Text); } Please remember that item.Summary is not the same as item.Content. As you see in the feed sample I provided, the content is surrounded by CDATA, meaning that it can provide HTML data to the receiving end. If I am going to call item.Content I will get an “Object reference not set to an instance of an object.” due to the fact that it is content:encoded instead of content. To read the content in this case, I am going to use this: foreach (SyndicationItem item in feed.Items) { foreach (SyndicationElementExtension ext in item.ElementExtensions) { if (ext.GetObject().Name.LocalName == "encoded") Debug.Print(ext.GetObject().Value); } } This will prevent the above mentioned exception and will read the string representation of the item content.
June 3, 2010
by Denzel D.
· 20,696 Views
article thumbnail
Iterator Pattern Tutorial with Java Examples
Learn the Iterator Design Pattern with easy Java source code examples as James Sugrue continues his design patterns tutorial series, Design Patterns Uncovered
June 3, 2010
by James Sugrue
· 62,218 Views · 1 Like
article thumbnail
JavaScript: Creating timestamps with time zone offsets
I was converting the example code of my Windows Azure session to Visual Studio 2010 solution called MVC Time Planner when I discovered some date and time offset issues in my JavaScript code. In this posting I will show you some useful tricks you can use to convert JavaScript dates and times to timestamps. Date.getTime() returns UTC When you call getTime method on Date object you get the number of milliseconds from Unix epoch. Although your current Date object keeps time with some offset getTime gives seconds in UTC. Keep this in mind when creating timestamps if you are not living on zero-meridian. var currentDate = selectedDate; // current date with offset var currentTime = currentDate.getTime(); // offset is ignored This is pretty awkward, unexpected and unintuitive behavior but you have to keep in mind that all date and time calculations must use same time system to give appropriate results. Date.getTimezoneOffset() getTimezoneOffset method returns you the amount of minutes you have to add to your current timestamp to convert it to UTC time. If your time zone is UTC+3 then getTimezoneOffset returns you –180 because: UTC + 3 hours + (-180) minutes = UTC If your time zone is UTC-3 then UTC - 3 hours + 180 minutes = UTC Pretty simple math but confusing at first place. Getting timestamp with time zone In my application I have to give timestamp for selected dates and times to server. I need to find correct amount of seconds from Unix epoch so users can save times based on their region and not by UTC. Here is how calculate timestamps. var currentDate = selectedDate; var currentTime = currentDate.getTime(); var localOffset = (-1) * selectedDate.getTimezoneOffset() * 60000; var stamp = Math.round(new Date(currentTime + localOffset).getTime() / 1000); On server side I use the following method to convert timestamp to date. This method is borrowed from CodeClimber blog posting Convert a Unix timestamp to a .NET DateTime. private static DateTime ConvertFromUnixTimestamp(double timestamp) { var origin = new DateTime(1970, 1, 1, 0, 0, 0, 0); return origin.AddSeconds(timestamp); } Conclusion Playing with dates and times is always interesting thing to do because there are many different time zones in the world and supporting them all is not easy thing to do. Inside the system we must be able to keep all dates in appropriate system and usually it is UTC. This posting showed you some tricks about how to play with local times in JavaScript.
June 1, 2010
by Gunnar Peipman
· 53,987 Views · 1 Like
article thumbnail
Bridge Pattern Tutorial with Java Examples
Learn the Bridge Design Pattern with easy Java source code examples as James Sugrue continues his design patterns tutorial series, Design Patterns Uncovered
June 1, 2010
by James Sugrue
· 108,504 Views · 3 Likes
article thumbnail
Swedish Defence Research on the NetBeans Platform (Part 1)
In 2003 the Swedish Defence Research Agency (FOI) started to consolidate work within the simulation domain to use the same simulation framework where applicable. To meet this end, that is, a distributed simulation architecture, the high level architecture (HLA) was selected to ease collaboration between research projects. It soon became clear that a scenario editor and scenario engine were needed to manage distributed simulations. Existing products filling this need, at the time, were either too expensive or not flexible enough for the purpose; a scenario tool needed to be developed. Requirements One requirement for the scenario tool was to use as few licensed software packages as possible and to be able to run on UNIX, Linux, and Windows. For many reasons, Java was the obvious choice to develop this scenario tool. Another requirement for the scenario tool was to have the whole scenario of a simulation in one central location. That includes setup of participating applications in a distributed simulation and which applications should participate. One of the software engineers in the project, Mikael Brännström, had done previous work on a demo using the NetBeans Platform and the decision was made to use the NetBeans Platform as the base for the scenario tool. Scenario Model The central component for a simulation is, of course, the scenario. The type of content in a scenario is described in a scenario model. Both scenario and scenario model can be represented in XML. Below is a representation (click to enlarge it) of a scenario and the simulation-related classes: The Scenario contains the main components of the simulation, entities, paths and coverage diagrams. These objects are persistent and are editable in NetScene. An Entity describes a physical or an abstract part in the simulation, for example a vehicle or a part of a software system. An Entity has a set of attributes, for example position or color. It also contains parameters that describe the relation to the parent, or container, of the entity, for example the relative position and orientation of a camera entity to the human that are carrying the camera. An Entity can have an EntityModel that performs some behavior of the entity. An EntityModel is executed by the SimulationEngine during the simulation and it has full access to the rest of the scenario. An EntityModel can model behavior of the entity, such as motion or sending Messages. A Message is an object used to handle communications between entity models and/or plug-ins, for example a sensor track or A Path contains a number of waypoints. A Path can be used by for example a motion model. Different interpolations can be selected for a path. A CoverageDiagram is used by for example sensor coverage. The scenario model is the scenario palette that hierarchically describes the components which can be used to create a scenario. The scenario model describes: data types: simple or complex entity classes: class hierarchy, attributes, relations between entities and default values message classes: parameters coverage diagram classes: parameters Scenario Creation The top left window contains a representation of the current scenario. It contains all entities, paths and coverage diagrams of the scenario. It also contains those scenarios that are included from the current scenario. The top right window contains scenarios and game configurations. These nodes are identified from the project files with MIME-resolvers. From this window scenarios can be merged or included to the current scenario. A merged scenario simply adds content to the current scenario. An included scenario acts as a reference to the included scenario, enabling several scenarios to be edited in the same context. The bottom left window contains a representation of the current scenario model. Entities and entity models can be dragged and dropped from this window to the middle window to create new entities or to add entity models to existing entities. The bottom right window contains a customizable properties window that can be configured by the user. It also differs from the normal property view in the way that it contains tools for the user to quickly manipulate complex types of the selected node. The middle window contains a map of the current scenario. Several maps can be open at the same time. Maps can be geo-referenced images, WMS maps and 3D maps. These windows also supply several tools for editing the scenario spatially. In part 2, you will read about concept development & experimentation with NetScene, as well as NetScene's plugins, and the applicability of these developments to multi-sensor systems. Now continue to part 2...
June 1, 2010
by Robert Forsgren
· 9,588 Views
article thumbnail
Creating Master-Detail Forms with Vaadin and Grails
In the article, Groovy, Grails and Vaadin, Petter Holmström outlined an example of using Vaadin with Grails, to build a simple data bound UI for a single database table. This was a great article that showed how one can quickly build a web-based solution that behaves very much like a typical client-server application. However, there are many instances where we need to be able to build an entry screen which allows the user to update both the master record and its detail records at the same time, such as in an Invoice entry screen. In this article I looked at extending the example in the above article, leveraging the simplicity of the Vaadin framework and the GORM capabilities, to build a master-detail example. After years of doing development using Oracle Forms, I liked the way it provides generic functions on each form (or data block) to allow users to add new records, delete them, query them and navigate from one record to the next. Furthermore, in Oracle Forms, you could provide a data grid to allow the user to edit the related detail table (such as the invoice lines in an Invoice document) and keeps these records in sync with the Invoice header (master) record. This is a first attempt at reproducing some of these capabilities using Vaadin and Grails. The master-detail data model The example here is an extension of the Petter Holmström model of the Trip Planner. In the original example, there is a table holding information on trips taken by the user. We will extend that example by having a one-to-many relation with a table of the places that are visited in each trip. This is the code for the Trip domain class. Notice that we are using Grails 1.3.1 which, by default, puts the domain class into the tripplanner package. package tripplanner class Trip { static constraints = { name(nullable: true) city(nullable: true) startDate(nullable: true) endDate(nullable: true) purpose(nullable: true) notes(nullable: true) } String name String city Date startDate Date endDate String purpose String notes static hasMany = [ places : Place ] static mapping = { places lazy:false, cascade:"all,delete-orphan" } } We have made the fields nullable for ease of inserting the record into the table. We also created the one-to-many relation with the Place domain class, and put in the mapping to cascade the deletion and updates to the sub-table class. We also need to change the relation from lazy to eager to ensure that the all detail records are loaded at the same time as the master (header) record. As for the Place domain class, we have 2 fields; name of the place we visited and a description field. In addition, we also put in a transient field, "_deleted", hich we will use to mark a detail record for deletion. package tripplanner class Place { static constraints = { name(nullable: true) description(nullable: true) } String name String description boolean _deleted static transients = [ '_deleted' ] static belongsTo = [trip:Trip] } The master-detail form Now, we need to change the VaadinApp class. Instead of listing the master record in a table to be selected for editing, I have opted to follow the Oracle Forms style for letting the user query for master records using Query By Example (QBE). The standard GORM and Hibernate infrastructure allows the use of a "example" object as a query pattern to extract a subset of records. This unfortunately is not exactly how Oracle Forms QBE works as Oracle Forms allows the user to put in "A%" patterns to query for values that starts with "A" and ">999" to query for values that is bigger than 999. The QBE in GORM only allows exact matches. We will accept this limitation for this example. So now we need a set of buttons to allow the user to: New - Add a new record data entry Save - Saves the current record to the database, including the changes done to the detail table Del - Deletes the current master record and the associated detail records EnterQ - Enters into Query mode which allows the user to provide a pattern for a QBE search ExecQ - Executes the Query and shows the first matching record from the query ExitQ - Exits out of Query mode and goes back to New record mode Prev - Go to previous record if there any queried records Next - Go to next record if there are any queried records These buttons are located at the top of the master record form. Error messages which arise from the save / update button are listed at the top of the master record form fields (in the "description field" of the Vaadin Form). There is also a status indicator label located at the footer of the master record form ("footer section" of the Vaadin Form). The status label will show the current mode of the master record entry screen and also the current record number if this is part of a query set. Below the master record form is the editable, selectable detail records table which is located in its own panel. Users are allowed to edit the detail record table only if the master record is in Edit mode. This means that users need to save the newly created master (header) record before that they can add any detail records. The detail record table has a column for all the editable, visible records excluding the "_deleted" field which is for internal use only. To manipulate the detail records, we provide 2 buttons to add a new detail record (the "+" button) or delete the selected detail record (the "-" button). All additions, deletions or even updates are only saved to the database after the user clicks on the "Save" button in the master (header) record form. As the user moves from one master record to the next using the "Prev" and "Next" buttons in the master table form, the detail table will be synchronized accordingly. package tripplanner import com.vaadin.ui.* import com.vaadin.data.* import com.vaadin.data.util.* class VaadinApp extends com.vaadin.Application { def query def rec_pos def container = new BeanItemContainer(Place.class) def master_fields = ["name", "purpose", "startDate", "endDate", "city", "notes"] def saveButton def newButton def delButton def entQButton def exeQButton def extQButton def prevButton def nextButton def statusLabel def pnlDetail void new_mode(editor) { def tripInstance = new Trip() editor.itemDataSource = new BeanItem(tripInstance) editor.visibleItemProperties = master_fields editor.description = "" container.removeAllItems() saveButton.setEnabled(true) delButton.setEnabled(false) entQButton.setEnabled(true) extQButton.setEnabled(false) statusLabel.setValue "New Mode" pnlDetail.setEnabled(false) } void init() { //def window = new Window("Trip Maintenance", new SplitPanel(SplitPanel.ORIENTATION_HORIZONTAL)) def window = new Window("Trip Maintenance") setMainWindow window // Form Panel def panel = new Panel("Trip Maintenance") panel.setSizeFull() panel.setLayout(new VerticalLayout()); // Trip editor def tripEditor = new Form() tripEditor.setSizeFull() tripEditor.layout.setMargin true tripEditor.immediate = true tripEditor.visible = true // status bar - shows the mode of the form statusLabel = new Label("New Mode") // define master form buttons saveButton = new Button("Save") newButton = new Button("New") delButton = new Button("Del") entQButton = new Button("EnterQ") exeQButton = new Button("ExecQ") extQButton = new Button("ExitQ") prevButton = new Button("Prev") nextButton = new Button("Next") // set initial state of buttons delButton.setEnabled(false) extQButton.setEnabled(false) // default is New Mode def v_tripInstance = new Trip() tripEditor.itemDataSource = new BeanItem(v_tripInstance) tripEditor.visibleItemProperties = master_fields //new_mode(tripEditor) // panel for detail form pnlDetail = new Panel() pnlDetail.setEnabled(false) // table to hold the detail form rows def table = new Table() table.containerDataSource = container table.selectable = true table.editable = true table.setSizeFull() table.visibleColumns = ["name", "description"] table.immediate = true // toolbar for the detail form manipulation def toolbar = new HorizontalLayout() // buttons for detail form // button to add new row to detail form def addRowButton = new Button("+", new Button.ClickListener() { void buttonClick(Button.ClickEvent event) { def placeInstance = new Place() def tripInstance = tripEditor.itemDataSource.bean tripInstance.addToPlaces(placeInstance) container.addBean placeInstance } }) toolbar.addComponent addRowButton // button to delete current row from detail form def delRowButton = new Button("-", new Button.ClickListener() { void buttonClick(Button.ClickEvent event) { if (table.value) { def placeInstance = table.value placeInstance._deleted = true container.removeItem(placeInstance) table.value = null } } }) toolbar.addComponent delRowButton // detail panel has the table rows and the toolbar pnlDetail.addComponent toolbar pnlDetail.addComponent table // master form buttons // save record button saveButton.addListener(new Button.ClickListener() { void buttonClick(Button.ClickEvent event) { Trip.withTransaction { status -> table.commit() def tripInstance = tripEditor.itemDataSource.bean def _toBeDeleted = tripInstance.places.findAll {it._deleted} if (_toBeDeleted) { tripInstance.places.removeAll(_toBeDeleted) } if (!tripInstance.save(flush:true)) { tripEditor.description = "Error:" tripInstance.errors.allErrors.each { error -> tripEditor.description = tripEditor.description + "" + "Field [${error.getField()}] with value [${error.getRejectedValue()}] is invalid" } tripEditor.description = tripEditor.description + "" window.showNotification "Could not save changes" } else { tripEditor.description = "" window.showNotification "Changes saved" delButton.setEnabled(true) statusLabel.setValue("Edit Mode"); pnlDetail.setEnabled(true) populate_container(container,tripInstance.places) } } } }) // new record button newButton.addListener(new Button.ClickListener() { void buttonClick(Button.ClickEvent event) { new_mode(tripEditor) } }) // delete record button delButton.addListener(new Button.ClickListener() { void buttonClick(Button.ClickEvent event) { if (tripEditor.itemDataSource.bean) { Trip.withTransaction { status -> def tripInstance = tripEditor.itemDataSource.bean tripInstance.delete(flush:true) } } new_mode(tripEditor) } }) // enter query mode entQButton.addListener(new Button.ClickListener() { void buttonClick(Button.ClickEvent event) { def tripInstance = new Trip() def newBean = new BeanItem(tripInstance) tripEditor.itemDataSource = newBean tripEditor.visibleItemProperties = master_fields tripEditor.description = "" saveButton.setEnabled(false) delButton.setEnabled(false) entQButton.setEnabled(false) extQButton.setEnabled(true) statusLabel.setValue("Query Mode"); pnlDetail.setEnabled(false) } }) // execute query exeQButton.addListener(new Button.ClickListener() { void buttonClick(Button.ClickEvent event) { tripEditor.commit() def example = (Trip) tripEditor.itemDataSource.bean query = Trip.findAll(example) rec_pos = 0 tripEditor.description = "" entQButton.setEnabled(true) extQButton.setEnabled(false) if (query.size > 0) { def next_rec = query[rec_pos] tripEditor.itemDataSource = new BeanItem(next_rec) tripEditor.visibleItemProperties = master_fields saveButton.setEnabled(true) delButton.setEnabled(true) statusLabel.setValue("Edit Mode. Record " + (rec_pos+1) + "/" + query.size); pnlDetail.setEnabled(true) populate_container(container,next_rec.places) } else { window.showNotification "No record found" new_mode(tripEditor) } } }) // exit query mode. Back to New mode extQButton.addListener(new Button.ClickListener() { void buttonClick(Button.ClickEvent event) { new_mode(tripEditor) } }) // edit mode, previous record prevButton.addListener(new Button.ClickListener() { void buttonClick(Button.ClickEvent event) { if (!query) { window.showNotification "No query result" return } if (rec_pos > 0) { rec_pos-- def next_rec = query[rec_pos] tripEditor.itemDataSource = new BeanItem(next_rec) tripEditor.visibleItemProperties = master_fields saveButton.setEnabled(true) statusLabel.setValue("Edit Mode. Record " + (rec_pos+1) + "/" + query.size) pnlDetail.setEnabled(true) populate_container(container,next_rec.places) } } }) // edit mode, next record nextButton.addListener(new Button.ClickListener() { void buttonClick(Button.ClickEvent event) { if (!query) { window.showNotification "No query result" return } if (rec_pos < query.size - 1) { rec_pos++ def next_rec = query[rec_pos] tripEditor.itemDataSource = new BeanItem(next_rec) tripEditor.visibleItemProperties = master_fields saveButton.setEnabled(true) statusLabel.setValue("Edit Mode. Record " + (rec_pos+1) + "/" + query.size) pnlDetail.setEnabled(true) populate_container(container,next_rec.places) } } }) // put the status bar on the footer of the master form tripEditor.footer = new HorizontalLayout() tripEditor.footer.addComponent statusLabel // put all master form buttons into a horizontal panel def btnPanel = new HorizontalLayout() btnPanel.addComponent saveButton btnPanel.addComponent newButton btnPanel.addComponent delButton btnPanel.addComponent entQButton btnPanel.addComponent exeQButton btnPanel.addComponent extQButton btnPanel.addComponent prevButton btnPanel.addComponent nextButton // construct master-detail form panel panel.addComponent btnPanel panel.addComponent tripEditor panel.addComponent pnlDetail // set panel to main window mainWindow.addComponent panel } // routine to populate the container with the detail records void populate_container(container, details) { container.removeAllItems() details.each { if (!it._deleted) container.addBean it } } } A walkthrough of the above VaadinApp code is as follows. The query object stores the list of "Trip" instances that is returned from a QBE query. The rec_pos is an index into the above list for the currently displayed record. The master_fields stores the list of master record fields that is visible on the form We put some of the buttons, status label and detail panel object as the object variables so that they can be access by helper routines The new_mode routine is to put the form into the New mode, which occurs multiple times in the whole code The init routine is where the whole window and form is defined The form is laid out with the master record buttons at the top, followed by the master record form, and then the detail table sub-panel below that In the detail sub-panel, there are 2 buttons, "+" and "-" which adds a detail to the Table and the master record instance and removes a detail record, respectively. These are not put into a GORM Transaction as we only want to save (flush) the record when the "Save" button is saved. The really tricky part of the whole form is in the master record buttons. For the "Save" button, we first force the detail table to update the source records in the master collection. Then we delete all the detail records which are marked for deletion, where the "_deleted" field is set to true. Finally the master record is saved by calling the "save" method in the tripInstance bean object. Any error messages are put into the "description field" of the master record form. If everything is fine, then the form is put into "Edit" mode for further editing including adding detail records into the Table below. The new button just puts a new Trip instance into the master record form (and disables the detail table panel) The delete button just deletes the master record. There is no need to "commit" the transaction as it is done automatically, and this differs from Oracle Forms The enter-query button just clears the fields to collect the parameters to search. If all the fields are null, then the QBE will match all records in the database Executing the query will run the "findAll(object)" method of the GORM domain instance. The return result is a List of matching instances. This is not quite scalable as the List needs to be stored in memory for the duration of the session or until the next query is run. This will need to be improved further. If there are any returned records, then the master form will display the first record and put it in "Edit" mode Exiting the Query mode will return the form to the New mode The previous and next buttons will update the master record form and the container of the detail table panel, thus keeping both screens in synchrony. The picture on the left shows the data entry screen with the detail records for the current master record. Future Direction To improve on this, we will need to componentize the whole form so that developers do not need to copy and paste the above template code and modify it for each form. Furthermore the "container" object above should be changeable to allow for other types of containers to be used but they should not be data-bound and leave the data-binding to the GORM objects and layer. Another suggestion is to create a Container component which is manipulated by the master table form buttons (add, save, delete, enter query, execute query, previous record, next record) and it then controls the master table entry Form. Finally, as mentioned in the Petter Holmström article, we are not really using any feature of Grails other than the GORM, and so, this entire example can be build using just Groovy, GORM and Vaadin.
May 31, 2010
by Chee-keong Lee
· 39,688 Views · 1 Like
  • Previous
  • ...
  • 875
  • 876
  • 877
  • 878
  • 879
  • 880
  • 881
  • 882
  • 883
  • 884
  • ...
  • Next
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

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

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook
×