• Fat Cats Boardgame
  • Wicket UI Library
  • About Me

Java and Wicket web development thoughts, tutorials, and tips

roman@coderdreams.com
Coder DreamsCoder Dreams
  • Fat Cats Boardgame
  • Wicket UI Library
  • About Me

Customizing your codebase for each customer using Enumerations

July 26, 2019 Posted by Roman Sery customization, enum, java No Comments

The problem

So you are really doing well for yourself and have many new customers for your application! Good job, but with many customers, come plenty of headaches.

As a simple example, let’s examine user names. You have a UserService that contains a function that accepts a user and returns the user name. There are many ways to do it, and different customers may prefer to display it in different ways. You can choose to display:

  • last name, first name
  • first name, last initial
  • last name (user ID)

To complicate things, a new customer has requested that user names be displayed only for active users. Otherwise, they want it to display as “Temp-user-${userId}”.

A poor solution

Let’s first implement this using a simple approach:

public String getUserName(User usr) {
        String customer = Utils.getCustomer();

        //for some, if not active, return "Temp-user-${userId}"
        if( ("CUST1".equals(customer) || "CUST2".equals(customer)) && !usr.isActive()) {
            return "Temp-user-(" + usr.getId() + ")";
        }

        if("CUST3".equals(customer)) {
            //last name, first name
            return usr.getLastName() + ", " + usr.getFirstName();
        }

        if("CUST4".equals(customer) || "CUST6".equals(customer)) {
            //first name, last initial
            return usr.getFirstName() + ", " + usr.getLastName().charAt(0);
        }

        if("CUST7".equals(customer)) {
            //last name (user ID)
            return usr.getLastName() + "(" + usr.getId() + ")";
        }
        return null;
    }

As you can see this approach can quickly get out of hand! As the number of customers increases, and more customizations are needed, this function will become very hard to maintain and become error prone. It’s also difficult to quickly gather the differences between customers just by glancing at the code. But we can do better!

A better solution

Using the techniques we learned in the previous blog post, we can create an enumeration that will define all the customizations available to our customers, and then use property files to allow each customer to override the default behavior.

Let’s say we want our application to, by default, display users as “last name, first name” and to not take into account the user’s status. We can define this in the below enumeration SiteConfig:

public enum SiteConfig {
    SHOW_INACTIVE_USERS_AS_TEMP("no"),
    USER_DISPLAY_TYPE("LAST_FIRST")
    ;

    private String value;
    SiteConfig(String value) {
        this.value = value;
    }

    public boolean getBoolean() {
        return BooleanUtils.toBoolean(value);
    }

    public <T extends Enum<T>> T getEnum(final Class<T> enumType) {
        return Enum.valueOf(enumType, value);
    }


    static {
        String customer = Utils.getCustomer();
        if (customer != null) {
            loadFromProperties(Utils.loadProperties("site_config_" + customer + ".properties"));
        }
    }

    private static void loadFromProperties(Properties customerProps) {
        if (customerProps != null) {
            SiteConfig[] arr = SiteConfig.values();
            for (SiteConfig s : arr) {
                if (customerProps.containsKey(s.name())) {
                    s.value = customerProps.getProperty(s.name());
                }
            }
        }
    }
}

SiteConfig defines two customizations available to customers, and we can add others as needed. The default behaviors are passed into the constructor and they can be overridden by each customer by creating a properties file such as site_config_CUST1.properties

SHOW_INACTIVE_USERS_AS_TEMP=yes
USER_DISPLAY_TYPE=LAST_USERID

Now let’s re-implement our getUserName method, to make use of SiteConfig:

 public String getUserName(User usr) {
        //for some, if not active, return "Temp-user-${userId}"
        if(!usr.isActive() && SiteConfig.SHOW_INACTIVE_USERS_AS_TEMP.getBoolean()) {
            return "Temp-user-(" + usr.getId() + ")";
        }

        UsernameDisplayType displayType = SiteConfig.USER_DISPLAY_TYPE.getEnum(UsernameDisplayType.class);

        if(UsernameDisplayType.LAST_FIRST == displayType) {
            //last name, first name
            return usr.getLastName() + ", " + usr.getFirstName();
        } else if(UsernameDisplayType.FIRST_LAST_INITIAL == displayType) {
            //first name, last initial
            return usr.getFirstName() + ", " + usr.getLastName().charAt(0);
        } else if(UsernameDisplayType.LAST_USERID == displayType) {
            //last name (user ID)
            return usr.getLastName() + "(" + usr.getId() + ")";
        }
        return null;
    }

The new method makes it easy to add other display types and associated logic without having any knowledge of customers. It also doesn’t need to be modified as customers are added or existing customers choose a different display type.

Check out the full code and simple app below!

https://github.com/RomanSery/codesnippets

No Comments
Share
7

About Roman Sery

I've been a software developer for over 10 years and still loving Java!

You also might be interested in

Reducing Wicket page size part 2: AttributeModifier and AttributeAppender

Sep 22, 2019

Reducing Wicket page size is one of the most important things you can do for performance. In part 2, learn how and when to replace AttributeModifier and AttributeAppender by overriding onComponentTag to squeeze out maxiumum perfomance!

Rent Day

Rent Day

May 12, 2021

I’m happy to announce the launch of Rent Day! If[...]

Wicket quick tip #4: Change default AjaxChannel to Active

Jul 7, 2020

Change the default behavior of Wicket's ajax request processing in order to avoid some common bugs.

Categories

  • aws
  • customization
  • database
  • debugging
  • enum
  • java
  • models
  • performance
  • projects
  • react
  • software design
  • Spring
  • tool
  • Uncategorized
  • wicket

Recent Posts

  • Rent Day
  • Self-contained Wicket Fragments
  • Pros and cons of unit testing
  • Themeable React Monopoly board
  • Please dont use client-specific release branches

Recent Comments

  • TCI Express Thanks for sharing such insightful information. TCI Express truly stands out as the best air logistics company, offering fast, secure, and efficient air express and cold chain transportation services....

    Tracking down a bug in production Wicket application ·  March 25, 2025

  • Tom Error: A zip file cannot include itself Can you please correct the plugin part so it doesn't use the same folder as input?

    Deploying Spring Boot app to AWS Beanstalk with Nginx customization ·  September 3, 2021

  • Golfman: Reality always wins I've used both Wicket and front-end JS frameworks and, having worked extensively on both, I can tell you that "Speed of development" is definitely NOT with the JS frameworks. You basically end up...

    Five reasons you should use Apache Wicket ·  August 29, 2021

  • Kiriller Sorry can not agree with you, wicket might be a well built technical framework. But the advantages of using a front-end framework like react.js and vue.js can not be beaten by Wicket nowadays. - Speed...

    Five reasons you should use Apache Wicket ·  August 23, 2021

  • Bernd Lauert Sorry but i have to refute your claims with the following arguments: 1. the Wicket community may be small but it is also very responsive, you usually get a helpful answer from the core devs on the...

    Five reasons you should use Apache Wicket ·  July 1, 2021

Archives

  • May 2021
  • October 2020
  • September 2020
  • August 2020
  • July 2020
  • June 2020
  • May 2020
  • April 2020
  • March 2020
  • February 2020
  • January 2020
  • December 2019
  • November 2019
  • October 2019
  • September 2019
  • August 2019
  • July 2019

Contact Me

Send Message
Prev Next