au.org.ala.biocache.util.CollectionsCache.java Source code

Java tutorial

Introduction

Here is the source code for au.org.ala.biocache.util.CollectionsCache.java

Source

/**************************************************************************
 *  Copyright (C) 2011 Atlas of Living Australia
 *  All Rights Reserved.
 * 
 *  The contents of this file are subject to the Mozilla Public
 *  License Version 1.1 (the "License"); you may not use this file
 *  except in compliance with the License. You may obtain a copy of
 *  the License at http://www.mozilla.org/MPL/
 * 
 *  Software distributed under the License is distributed on an "AS
 *  IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 *  implied. See the License for the specific language governing
 *  rights and limitations under the License.
 ***************************************************************************/
package au.org.ala.biocache.util;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestOperations;

import javax.inject.Inject;
import java.lang.reflect.Field;
import java.util.LinkedHashMap;
import java.util.List;

/**
 * Provides access to the collection and institution codes and names from the Collectory.
 * Uses the registry webservices to get a map of codes & names for institutions and collections
 * and caches these. Cache is automatically updated after a configurable timeout period.
 *
 * NC 2013-0925 Changed the collection cache to be async scheduled
 *
 * @author "Nick dos Remedios <Nick.dosRemedios@csiro.au>"
 */
@Component("collectionsCache")
public class CollectionsCache {

    protected LinkedHashMap<String, String> dataResources = new LinkedHashMap<String, String>();
    protected LinkedHashMap<String, String> dataProviders = new LinkedHashMap<String, String>();
    protected LinkedHashMap<String, String> tempDataResources = new LinkedHashMap<String, String>();
    protected LinkedHashMap<String, Integer> downloadLimits = new LinkedHashMap<String, Integer>();
    protected LinkedHashMap<String, String> institutions = new LinkedHashMap<String, String>();
    protected LinkedHashMap<String, String> collections = new LinkedHashMap<String, String>();
    protected LinkedHashMap<String, String> dataHubs = new LinkedHashMap<String, String>();
    protected List<String> institution_uid = null;
    protected List<String> collection_uid = null;
    protected List<String> data_resource_uid = null;
    protected List<String> data_provider_uid = null;
    protected List<String> data_hub_uid = null;

    @Value("${registry.url:http://collections.ala.org.au/ws}")
    protected String registryUrl;

    //NC 20131018: Allow cache to be disabled via config (enabled by default)
    @Value("${caches.collections.enabled:true}")
    protected Boolean enabled = null;
    /** Spring injected RestTemplate object */
    @Inject
    private RestOperations restTemplate; // NB MappingJacksonHttpMessageConverter() injected by Spring
    /** Log4J logger */
    private final static Logger logger = Logger.getLogger(CollectionsCache.class);

    /**
     * Get the institutions
     *
     * @return
     */
    public LinkedHashMap<String, String> getInstitutions() {
        return this.institutions;
    }

    public LinkedHashMap<String, String> getDataResources() {
        return this.dataResources;
    }

    public LinkedHashMap<String, String> getDataProviders() {
        return this.dataProviders;
    }

    public LinkedHashMap<String, String> getTempDataResources() {
        return this.tempDataResources;
    }

    public LinkedHashMap<String, String> getCollections() {
        return this.collections;
    }

    public LinkedHashMap<String, String> getDataHubs() {
        return this.dataHubs;
    }

    public LinkedHashMap<String, Integer> getDownloadLimits() {
        return downloadLimits;
    }

    /**
     * Update the entity types (fields)
     */
    @Scheduled(fixedDelay = 3600000L) //every hour
    public void updateCache() {
        if (enabled) {
            logger.info("Updating collectory cache...");
            this.collections = getCodesMap(ResourceType.COLLECTION, collection_uid);
            this.institutions = getCodesMap(ResourceType.INSTITUTION, institution_uid);
            this.dataResources = getCodesMap(ResourceType.DATA_RESOURCE, data_resource_uid);
            this.dataProviders = getCodesMap(ResourceType.DATA_PROVIDER, data_provider_uid);
            this.tempDataResources = getCodesMap(ResourceType.TEMP_DATA_RESOURCE, null);
            this.dataHubs = getCodesMap(ResourceType.DATA_HUB, data_hub_uid);
            this.dataResources.putAll(tempDataResources);
        } else {
            logger.info("Collectory cache has been disabled");
        }

    }

    /**
     * Do the web services call. Uses RestTemplate.
     *
     * @param type
     * @return
     */
    protected LinkedHashMap<String, String> getCodesMap(ResourceType type, List<String> guids) {
        LinkedHashMap<String, String> entityMap = null;
        logger.info("Updating code map with " + guids);
        try {
            // grab cached values (map) in case WS is not available (uses reflection)
            Field f = CollectionsCache.class.getDeclaredField(type.getType() + "s"); // field is plural form
            entityMap = (LinkedHashMap<String, String>) f.get(this);
            logger.debug("checking map size: " + entityMap.size());
        } catch (Exception ex) {
            logger.error("Java reflection error: " + ex.getMessage(), ex);
        }

        try {
            entityMap = new LinkedHashMap<String, String>(); // reset now we're inside the try
            final String jsonUri = registryUrl + "/" + type.getType() + ".json";
            logger.debug("Requesting: " + jsonUri);
            List<LinkedHashMap<String, String>> entities = restTemplate.getForObject(jsonUri, List.class);
            logger.debug("number of entities = " + entities.size());

            for (LinkedHashMap<String, String> je : entities) {
                if (addToCodeMap(je.get("uid"), guids)) {
                    entityMap.put(je.get("uid"), je.get("name"));
                }
            }
        } catch (Exception ex) {
            logger.error("RestTemplate error: " + ex.getMessage(), ex);
        }

        return entityMap;
    }

    private boolean addToCodeMap(String uid, List<String> guids) {
        if (guids != null) {
            return guids.contains(uid);
        }
        return true;
    }

    /**
     * Inner enum class
     */
    public enum ResourceType {
        INSTITUTION("institution"), COLLECTION("collection"), DATA_RESOURCE("dataResource"), DATA_PROVIDER(
                "dataProvider"), TEMP_DATA_RESOURCE("tempDataResource"), DATA_HUB("dataHub");

        private String type;

        ResourceType(String type) {
            this.type = type;
        }

        public String getType() {
            return type;
        }
    }
}