0

I'm having a string with delimiter : which has two tokens (old & new token). I've two scenarios - I may get

  • only old token oldToken-NmH0FKDKiITkIDDopLDkDD
  • old and new token oldToken-NmH0FKDKiITkIDDokDDsOxMdUU2qPnRxKiY:newToken-IdsfdWeRrrfziTjHNGfyKfK9YCoEsy6nTDI

Step 1: To identify old and new token, the string is appended with oldToken- and newToken-. I'm checking if the string contains both old and new tokens, if yes get the newToken value or else get the oldtoken value. To get the actual value, I'm removing this appended string based on condition

splitResult[1].replaceAll("newToken-", ""))

Step 2: Once I get the token value, checking this token exist in the map or else make an external call one by one by passing the token.

My challenge here is I'm duplicating replaceAll in a lot of places, how to get rid of this. Or is there any better way to refactor the below code, sorry I'm new to Java so please excuse me

Please find the code below:

public class Main {
    public static void main(String[] args) {

        // Scenario 1: This contains both the token
        String myKey = "oldToken-NmH0FKDKiITkIDDokDDsOxMdUU2qPnRxKiY:newToken-IdsfdWeRrrfziTjHNGfyKfK9YCoEsy6nTDI";

        // Scenario 2: This contains only one token
        // String myKey = "oldToken-NmH0FKDKiITkIDDopLDkDD";

        String[] splitResult = myKey.split(":");
        System.out.println(test(splitResult));

    }

    private static String test(String[] splitResult) {

        // Scenario 1: Map with value
        Map<String, String> myMap = new HashMap<>();
        myMap.put("NmH0FKDKiITkIDDokDDsOxMdUU2qPnRxKiY", "user1");
        myMap.put("IdsfdWeRrrfziTjHNGfyKfK9YCoEsy6nTDI", "user2");

        // Scenario 2: Empty Map
        // Map<String, String> myMap = new HashMap<>();

        String cache = null;
        if (splitResult.length >= 2) {
            if (splitResult[1].contains("newToken-") && splitResult[0].contains("oldToken-")) {

                cache = myMap.get(splitResult[1].replaceAll("newToken-", ""));
            }
        } else {
            cache = myMap.get(splitResult[0].replaceAll("oldToken-", ""));
        }

        // If no value in cache, make an external call with both the token
        if (cache == null) {
            String request = null;

            for (String getVal : splitResult) {
                if (getVal.contains("oldToken")) {
                    request = getVal.replaceAll("oldToken-", "");
                    System.out.println("request: " + request);
                    // Make an external call

                } else if (getVal.contains("newToken")) {
                    request = getVal.replaceAll("newToken-", "");
                    System.out.println("request: " + request);
                    // Make an external call
                }
            }
        }

        return cache;
    }

}

2 Answers 2

2

You can reduce the repetition by using a separate function responsible for extracting the needed token from a string. See getToken in the sample code below.

You can play around with the regex until it works for all of your strings, but here is an example. Refer to regexp documentation here.

As shown, you can separate the processing into two functions (or even more, depending on what else you need). You can use regexp capture groups denoted by parentheses. Note that (?:...) is a non-capturing group.

Edit You can encapsulate the token-related behaviors into a TokenPair class, where newToken may or may not be defined. This way, you can access both the new and old tokens when handling cache misses (and also have simple a function tokenInCache which gives the new token in the pair, only if it's available, to be checked against the cache).

public class Main {
   public static class TokenPair {
        public String oldToken;
        public String newToken;
        public TokenPair(String oldToken, String newToken) {
            this.oldToken = oldToken;
            this.newToken = newToken;
        }
        public TokenPair(String oldToken) {
            this.oldToken = oldToken;
            this.newToken = null;
        }
        public String tokenInCache() {
            if (newToken == null) {
                return oldToken;
            }
            return newToken;
        }
        public static TokenPair getToken(String input){
            Pattern p = Pattern.compile("^oldToken-([A-Za-z0-9]+)(?::newToken-([A-Za-z0-9]+))?");   // the pattern to search for
            Matcher m = p.matcher(input);
            if (m.matches()) {
                if (m.group(2) != null) {
                    return new TokenPair(m.group(1), m.group(2));
                } else {
                    return new TokenPair(m.group(1));
                }
            } else {
                return null;
            }

        }

        @Override
        public String toString() {
            return oldToken + (newToken == null ? "" : ":" + newToken);
        }
    }
    public static void main(String[] args) {
        // Scenario 1: This contains both the tokens
        String myKey1 = "oldToken-NmH0FKDKiITkIDDokDDsOxMdUU2qPnRxKiY:newToken-IdsfdWeRrrfziTjHNGfyKfK9YCoEsy6nTDI";

        // Scenario 2: This contains only one token
        String myKey2 = "oldToken-NmH0FKDKiITkIDDopLDkDD";

        TokenPair token = TokenPair.getToken(myKey1);
        System.out.println(token); // "NmH0FKDKiITkIDDokDDsOxMdUU2qPnRxKiY:IdsfdWeRrrfziTjHNGfyKfK9YCoEsy6nTDI");
        System.out.println(TokenPair.getToken(myKey2)); // "NmH0FKDKiITkIDDopLDkDD");


        // Scenario 1: Map with value
        Map<String, String> myMap = new HashMap<>();
        myMap.put("NmH0FKDKiITkIDDokDDsOxMdUU2qPnRxKiY", "user1");
        myMap.put("IdsfdWeRrrfziTjHNGfyKfK9YCoEsy6nTDI", "user2");

        processToken(myMap, token);
    }
    private static void processToken(Map<String, String> cache, TokenPair tokenPair) {

        String cacheValue = cache.get(tokenPair.tokenInCache());

        if (cacheValue == null) {
            if (tokenPair.newToken != null) {
                // do processing here with tokenPair.newToken;
            }
            // do processing here with tokenPair.oldToken;

        }
    }
}

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot for ur suggestion. But I've issue in processToken(), assume myMap doesn't have any value - in that scenario I've to make HTTP call. And the use case here is if myKey1 has two tokens then I've to make two HTTP call for each token, and for myKey2 - if no value exist in myMap - I've to make just one HTTP call since myKey2 contains only token. So how to handle this scenario. There is a high chance myMap as an empty. Basically I've to do some iteration - then extract token one by one and make an HTTP call. If you see my original post - I'm doing forEach. How to do handle this?
1

You can make it much cleaner by defining functions to get tokens.

private static String getOldToken(String myKey) {
    Matcher matcher = Pattern.compile("(?<=\\boldToken-)[^:]*").matcher(myKey);
    return matcher.find() ? matcher.group() : "";
}

private static String getNewToken(String myKey) {
    Matcher matcher = Pattern.compile("(?<=\\bnewToken-)[^:]*").matcher(myKey);
    return matcher.find() ? matcher.group() : "";
}

Explanation of the regex, (?<=\bnewToken-)[^:]*:

  • (?<=: Start of Lookbehind assertion.
  • ): End of Lookbehind assertion.
  • [^:]*: Any character except :, any number of times

Full code:

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {
    public static void main(String[] args) {

        // Scenario 1: This contains both the token
        String myKey = "oldToken-NmH0FKDKiITkIDDokDDsOxMdUU2qPnRxKiY:newToken-IdsfdWeRrrfziTjHNGfyKfK9YCoEsy6nTDI";

        // Scenario 2: This contains only one token
        // String myKey = "oldToken-NmH0FKDKiITkIDDopLDkDD";

        System.out.println(test(myKey));
    }

    private static String test(String myKey) {
        Map<String, String> myMap = new HashMap<>();

        String oldToken = getOldToken(myKey);
        String newToken = getNewToken(myKey);

        if (!oldToken.isBlank())
            myMap.put(oldToken, "user1");
        if (!newToken.isBlank())
            myMap.put(newToken, "user2");

        String cache = myMap.get(newToken);

        if (cache == null) {
            String request = oldToken;
            System.out.println("request: " + request);
            // Make an external call
        }

        return cache;
    }

    private static String getOldToken(String myKey) {
        Matcher matcher = Pattern.compile("(?<=\\boldToken-)[^:]*").matcher(myKey);
        return matcher.find() ? matcher.group() : "";
    }

    private static String getNewToken(String myKey) {
        Matcher matcher = Pattern.compile("(?<=\\bnewToken-)[^:]*").matcher(myKey);
        return matcher.find() ? matcher.group() : "";
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.