Java tutorial
/** * Copyright 2008-2015 Qualogy Solutions B.V. * * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.qualogy.qafe.core.datastore; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.logging.Logger; import org.apache.commons.lang.StringUtils; import com.qualogy.qafe.platform.distribution.DistributionFactory; //##hkr public class ApplicationLocalStore { private final static Logger logger = Logger.getLogger(ApplicationLocalStore.class.getName()); public final static String KEY_USER_ID = "$USER_ID"; public final static String KEY_SHARED_CACHE = "$SHARED_CACHE"; public final static char OBJECT_DELIMITER = '.'; public final static char CONTEXT_DELIMITER = '|'; public final static char ATTRIBUTE_DELIMITER = '@'; public final static String ATTRIBUTE_SIZE = "size"; private static ApplicationLocalStore singleton = null; private Map<String, Map<String, Object>> store; private ApplicationLocalStore() { store = DistributionFactory.getInstance().getDistributionManager().getCacheManager() .getDistributedMap(KEY_SHARED_CACHE); } public static ApplicationLocalStore getInstance() { if (singleton == null) { singleton = new ApplicationLocalStore(); } return singleton; } public void storeTemporary(String uuid, String key, Object value) { store(uuid, key, new TemporaryStoreItem(value)); } public void store(String uuid, String key, Object value) { debug("store: uuid=" + uuid + " - key=" + key + " - value=" + value); Map<String, Object> localStoreMap = store.get(uuid); debug("store: uuid=" + uuid + " - localStoreMap=" + localStoreMap); if (localStoreMap == null) { localStoreMap = new DataMap<String, Object>(); } localStoreMap.put(key, value); store(uuid, localStoreMap); debug("store: uuid=" + uuid + " - localStoreMap=" + localStoreMap); } public void deleteAll(String uuid) { Map<String, Object> localStoreMap = store.get(uuid); debug("delelteAll: uuid=" + uuid + " - localStoreMap=" + localStoreMap); if (localStoreMap != null) { localStoreMap.clear(); // Make changes affected to the store when using distributed cache in Google AppEngine store(uuid, localStoreMap); } } public void delete(String uuid, String key) { Map<String, Object> localStoreMap = store.get(uuid); debug("delete: uuid=" + uuid + " - localStoreMap=" + localStoreMap); if (localStoreMap != null) { localStoreMap.remove(key); // Make changes affected to the store when using distributed cache in Google AppEngine store(uuid, localStoreMap); } } public boolean exists(String uuid) { return (store.get(uuid) != null); } public boolean contains(String uuid, String key) { boolean contains = false; Map<String, Object> localStoreMap = store.get(uuid); if (localStoreMap != null) { contains = localStoreMap.containsKey(key); } debug("contains: uuid=" + uuid + " - key=" + key + " - contains=" + contains); return contains; } // CHECKSTYLE.OFF: CyclomaticComplexity public Object retrieve(String uuid, String key) { Object returnValue = null; Map<String, Object> localStoreMap = store.get(uuid); debug("retrieve: uuid=" + uuid + " - localStoreMap=" + localStoreMap); if (localStoreMap != null) { boolean hasChanges = false; if (key != null) { String[] keys = StringUtils.split(key, OBJECT_DELIMITER); if (keys != null && keys.length == 1 && !key.contains("" + ATTRIBUTE_DELIMITER)) { // simple property if (key.contains("[")) { returnValue = extractDataMapOfIndexFromList(localStoreMap, key); } else { returnValue = localStoreMap.get(key); } debug("retrieve: uuid=" + uuid + " - key=" + key + " - returnValue=" + returnValue); if (returnValue instanceof TemporaryStoreItem) { returnValue = ((TemporaryStoreItem) returnValue).getObject(); localStoreMap.remove(key); hasChanges = true; debug("retrieve: uuid=" + uuid + " - returnValue(TemporaryStoreItem)=" + returnValue); } } else if (keys.length == 2) { // nested object Object mapObject = null; if (keys[0].contains("[")) { mapObject = extractDataMapOfIndexFromList(localStoreMap, keys[0]); } else { mapObject = localStoreMap.get(keys[0]); } debug("retrieve: uuid=" + uuid + " - key=" + key + " - o=" + mapObject); if (mapObject instanceof Map) { returnValue = ((Map) mapObject).get(keys[1]); debug("retrieve: uuid=" + uuid + " - returnValue=" + returnValue); if (returnValue instanceof TemporaryStoreItem) { returnValue = ((TemporaryStoreItem) returnValue).getObject(); localStoreMap.remove(keys[1]); hasChanges = true; debug("retrieve: uuid=" + uuid + " - returnValue(TemporaryStoreItem)=" + returnValue); } } } else { if (key.contains("" + ATTRIBUTE_DELIMITER)) { String attribute = key.substring(key.indexOf(ATTRIBUTE_DELIMITER) + 1, key.length()); String elementKey = key.substring(0, key.indexOf(ATTRIBUTE_DELIMITER)); Object object = localStoreMap.get(elementKey); debug("retrieve: uuid=" + uuid + " - key=" + key + " - object=" + object); if (object instanceof Collection) { if (ATTRIBUTE_SIZE.equals(attribute)) { returnValue = ((Collection) object).size(); debug("retrieve: uuid=" + uuid + " - size=" + returnValue); } } } } } if (hasChanges) { // Make changes affected to the store when using distributed cache in Google AppEngine store(uuid, localStoreMap); } } return returnValue; } // CHECKSTYLE.ON: CyclomaticComplexity /** * Method to add or update the object in the localstore. * * Checks: * 1. if original is list and toBeAddOrUpdated is list, toBeAddOrUpdated * will replace old value * 2. if original is list and toBeAddOrUpdated is not a list, toBeAddOrUpdated * will be set(if object reference exists) or added to list * 3. if object in store is null, given object is stored * @param uuid * @param key * @param original * @return */ public void addOrUpdate(String uuid, String key, Object value) { Object updated = update(uuid, key, value); if (updated == null) { store(uuid, key, value); } } /** * Method to update the object in the localstore. * * Checks: * 1. if original is list and toBeAddOrUpdated is list, toBeAddOrUpdated * will replace old value * 2. if original is list and toBeAddOrUpdated is not a list, toBeAddOrUpdated * will be set(if object reference exists) or added to list * @param uuid * @param key * @param original * @return */ public Object update(String uuid, String key, Object value) { Object original = retrieve(uuid, key); if (original instanceof List) { if (value instanceof List) { original = value; } else { Iterator itr = ((List) original).iterator(); int index = 0; boolean found = false; while (itr.hasNext() && !found) { if (itr.next().equals(value)) { found = true; } else { index++; } } if (found) { ((List) original).set(index, value); } else { ((List) original).add(value); } } } else if (original != null) { original = value; } return value; } private Object extractDataMapOfIndexFromList(Map<String, Object> localStoreMap, String key) { String extractedKey = key.substring(0, key.indexOf("[")); int index = Integer.parseInt(key.substring(key.indexOf("[") + 1, key.indexOf("]"))); List<DataMap> retrievedList = (List<DataMap>) localStoreMap.get(extractedKey); return retrievedList.get(index); } private void store(String uuid, Map map) { store.put(uuid, map); } private void debug(String message) { logger.fine(message); } public String toLogString(String uuid) { return store.get(uuid) != null ? "LocalData for key [" + uuid + "]:\n" + store.get(uuid).toString() : null; } }