Java Ninja Chronicles By Norris Shelton

Things I learned in the pursuit of code

I had a Java array of Strings. I needed to be able to quickly locate each item, so I fed it into a LinkedHashSet.

                Map<String, Boolean> newTableNames = new LinkedHashMap<>(pokerTableNames.length);
                for (String pokerTableName : pokerTableNames) {
                    newTableNames.put(pokerTableName, false);
                }

Later in the code, I needed to grab an item out of the list. My first cut was involved a for-loop. I got the first KeyValueSet, then called remove witht the value.

An easier way seems to be…

String candidateTableName  = newTableNames.entrySet().iterator().next().getKey();

February 27th, 2015

Posted In: Java, java ninja, Javaninja

Tags: , ,

Leave a Comment

I needed to iterate over the values contained in a replicatedMap. I thought it would be as simple as:

hz.<Long, GameInfo>replicatedMap(DO.DESK_MAP, DO.DESK_MAP).values();

It would show that there were 2006 entries, but I couldn’t touch them.

I later stumbled upon the following:

hz.mapValues(DO.DESK_MAP);

This gave me a Collection of the values that I could iterate over.

February 26th, 2015

Posted In: Hazelcast, Java, java ninja, Javaninja

Tags: , , , ,

2 Comments

The dotCMS JSON API is pretty easy to use. It even tells you the query for the content that you are looking for. That makes it super easy to use. What I didn’t know was that the results default to a limit of 10 records.

Here was my original query.

http://youbet.com/api/content/render/false/query/+structureName:PokerTableNameAdjectives%20+(conhost:915f2552-793a-4f17-96d0-f0955fcc698f%20conhost:SYSTEM_HOST)%20+languageId:1*%20+deleted:false%20%20+working:true/orderby/modDate%20desc/limit/30

That was easy enough, but how to you specify more? You specify the optional limit. It’s pretty easy, once you know what you are looking for.

/api/content/limit/<integer-limit>

That was easy enough. Here is what the final query looks like.

http://youbet.com/api/content/render/false/query/+structureName:PokerTableNameAdjectives%20+(conhost:915f2552-793a-4f17-96d0-f0955fcc698f%20conhost:SYSTEM_HOST)%20+languageId:1*%20+deleted:false%20%20+working:true/orderby/modDate%20desc/api/content/limit/1000

February 26th, 2015

Posted In: Java, java ninja, Javaninja

Tags: , , , , ,

Leave a Comment

The usual usage of a Springframework RestTemplate is to get back an object. Sometimes the object will contain a list. What needs to happen when you need to get back a list of Strings? RestTemplate accepts a parameter that tells it what the data it receives will be put in. I used a String array. It converts the JSON object into a String[] and away I go.

                    String[] pokerTableNames =
                        restTemplate.getForObject(pokerSettingsService.getValueByName(PokerSettings.IGP_ADAPTER_URL) + "/poker/tableNames",
                            String[].class);

February 20th, 2015

Posted In: Java, java ninja, Javaninja, json, Spring

Tags: , , , , , , ,

Leave a Comment

This is something that I rarely do because I use IntelliJ IDEA. Here is one of the most complex commands I issue for Maven.

mvn -P dev -DskipTests=true clean install
  • -p dev -> which profile to run
  • -DskipTests=true -> do not run the automated tests
  • clean install -> clean all target directories and run an install

February 13th, 2015

Posted In: Maven

Tags: , , , ,

One Comment

I had a RESTful call to a dotCMS 2.x server worked out. I called it later in the day and a new property was being sent. This resulted in the following exception.

Method threw 'com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException' exception.
class com.cdi.igp.models.dotcms.PokerClient
stInode
 size = 3
 (3 known properties: "version", "whatsNew", "clientType"])
 size = 3
[Source: {"contentlets":[{...removed for brevity...}]}; line: 1, column: 29]
Unrecognized field "stInode" (class com.cdi.igp.models.dotcms.PokerClient), not marked as ignorable
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "stInode" (class com.cdi.igp.models.dotcms.PokerClient), not marked as ignorable (3 known properties: "version", "whatsNew", "clientType"])
 at [Source: ...removed for brevity...]}; line: 1, column: 29] (through reference chain: com.cdi.igp.core.dotcms.DotCmsPokerClientResponse["contentlets"]->java.util.ArrayList[0]->com.cdi.igp.models.dotcms.PokerClient["stInode"])

 size = 0

I fixed it by adding the following to the top of the class that I was mapping the data into.

@JsonIgnoreProperties(ignoreUnknown = true)

Problem solved.

February 3rd, 2015

Posted In: Java, java ninja, Javaninja

Tags: , , , , , , ,

Leave a Comment

Using the Springframework RestTemplate is usually fairly straight forward. In this case, it didn’t work. I had a URL that would work when I pasted it into the web browser and would also work in the Chrome Advanced Rest Client. Each time I tried to call it with a Spring Rest Template, I got a HTTP 406.

    /**
     * Gets the poker client content objects from dotCMS.
     * @return poker clients model object
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    public PokerClientsModel getPokerClients() throws InvocationTargetException, IllegalAccessException {

        String url = settingRepository.findSettingByIdSetting(SettingEnum.HOST_URL.key()).getValue() +
            "/api/content/render/false/query/+structureName:PokerClient%20+" +
            "(conhost:915f2552-793a-4f17-96d0-f0955fcc698f%20conhost:SYSTEM_HOST)" +
            "%20+languageId:1*%20+deleted:false%20%20+working:true/orderby/modDate%20desc";

        DotCmsPokerClientResponse dotCmsPokerClientResponse = restTemplate.getForObject(url,
                                                                                        DotCmsPokerClientResponse.class);
        PokerClientsModel pokerClientsModel = new PokerClientsModel();
        PokerClient pokerClient;
        for (DotCmsPokerClient dotCmsPokerClient : dotCmsPokerClientResponse.getDotCmsPokerClients()) {
            pokerClient = new PokerClient();
            BeanUtils.copyProperties(pokerClient, dotCmsPokerClient);
            pokerClientsModel.getPokerClients().add(pokerClient);
        }

        return pokerClientsModel;

    }

That just plain didn’t work.

Method threw 'org.springframework.web.client.HttpClientErrorException' exception.
406
Not Acceptable

 size = 8
UTF-8
406 Not Acceptable
org.springframework.web.client.HttpClientErrorException: 406 Not Acceptable

 size = 0

I thought about what the browser could be sending that I wasn’t. It hit me that the browser may be sending the content type as text/plain. It is a bit of a pain in the rear-end to send a content type on a get request. I eventually got to set the content type by using the Http Entity.

    /**
     * Gets the poker client content objects from dotCMS.
     * @return poker clients model object
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    public PokerClientsModel getPokerClients() throws InvocationTargetException, IllegalAccessException {

        String url = settingRepository.findSettingByIdSetting(SettingEnum.HOST_URL.key()).getValue() +
            "/api/content/render/false/query/+structureName:PokerClient%20+" +
            "(conhost:915f2552-793a-4f17-96d0-f0955fcc698f%20conhost:SYSTEM_HOST)" +
            "%20+languageId:1*%20+deleted:false%20%20+working:true/orderby/modDate%20desc";
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.TEXT_PLAIN);

        HttpEntity entity = new HttpEntity(headers);
        HttpEntity<String> dotCmsPokerClientResponse = restTemplate.exchange(url,
                                                                             HttpMethod.GET,
                                                                             entity,
                                                                             String.class);
        return pokerClientsModel;
    }

This did work better. No more HTTP 406, but the return object contained a blank contentlets array.

<200 OK,{"contentlets":[]},{Date=[Mon, 02 Feb 2015 15:26:09 GMT], Server=[Apache-Coyote/1.1], Content-Type=, Set-Cookie=[JSESSIONID=8CDC0C67730932FAEBBB729FBA5E2BBA; Path=/, ROUTEID=.1; path=/], Vary=[Accept-Encoding], Keep-Alive=[timeout=5, max=100], Connection=[Keep-Alive], Transfer-Encoding=[chunked]}>

Frustration set in and I was starting to get desperate. I got the idea of using HttpClient directly to make the call.

    /**
     * Gets the poker client content objects from dotCMS.
     * @return poker clients model object
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    public PokerClientsModel getPokerClients() throws InvocationTargetException, IllegalAccessException {

        String url = settingRepository.findSettingByIdSetting(SettingEnum.HOST_URL.key()).getValue() +
            "/api/content/render/false/query/+structureName:PokerClient%20+" +
            "(conhost:915f2552-793a-4f17-96d0-f0955fcc698f%20conhost:SYSTEM_HOST)" +
            "%20+languageId:1*%20+deleted:false%20%20+working:true/orderby/modDate%20desc";

        return get(url);
    }

    /**
     * Performs a HTTP get of the specified URL.
     * @param url the desired URL.
     * @return Http response body as a string
     */
    protected String get(String url) {
        HttpClient httpClient = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(url);
        ResponseHandler<String> responseHandler = new BasicResponseHandler();
        String responseBody = null;
        try {
            responseBody = httpClient.execute(httpGet, responseHandler);
        } catch (IOException e) {
            logger.error("IOException", e);
        } finally {
            // When HttpClient instance is no longer needed,
            // shut down the connection manager to ensure
            // immediate deallocation of all system resources
            httpClient.getConnectionManager().shutdown();
        }
        return responseBody;
    }

Success!!!!!

{"contentlets":[{"stInode":"d5af8654-aa65-4f2f-b2cd-bc6bf54753d5","owner":"norris.shelton","lastReview":"2015-01-30 16:21:56.226","modUser":"norris.shelton","identifier":"42ee0e8c-bd3c-4bae-ac51-b7837dc8e832","version":"000.000.000","clientType":"android","sortOrder":0,"modDate":"2015-01-30 16:21:56.238","host":"915f2552-793a-4f17-96d0-f0955fcc698f","whatsNew":"Initial Android Version","languageId":1,"inode":"ef33dbd6-2e47-44f7-a47f-daaa5c52e74b","folder":"SYSTEM_FOLDER"},{"stInode":"d5af8654-aa65-4f2f-b2cd-bc6bf54753d5","owner":"norris.shelton","lastReview":"2015-01-30 16:21:41.265","modUser":"norris.shelton","identifier":"b670a674-fb54-425a-93b8-432c8443e02d","version":"000.000.000","clientType":"ios","sortOrder":0,"modDate":"2015-01-30 16:21:41.278","host":"915f2552-793a-4f17-96d0-f0955fcc698f","whatsNew":"Initial IOS version","languageId":1,"inode":"929fb049-1c85-4376-bc9f-143981466a0a","folder":"SYSTEM_FOLDER"},{"stInode":"d5af8654-aa65-4f2f-b2cd-bc6bf54753d5","owner":"norris.shelton","lastReview":"2015-01-30 16:21:29.787","modUser":"norris.shelton","identifier":"df0ce56f-8e43-4169-9632-eb05fddd442f","version":"000.000.000","clientType":"flash","sortOrder":0,"modDate":"2015-01-30 16:21:29.8","host":"915f2552-793a-4f17-96d0-f0955fcc698f","whatsNew":"Initial Flash version","languageId":1,"inode":"8ff7fe3f-8064-42cf-8d9a-eaf6f65b52f9","folder":"SYSTEM_FOLDER"}]}

February 2nd, 2015

Posted In: Java, java ninja, Javaninja

Tags: , , , , , , , ,

Leave a Comment

LinkedIn Auto Publish Powered By : XYZScripts.com