All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.genexus.specific.java.GXSmartCacheProvider Maven / Gradle / Ivy

Go to download

Core classes for the runtime used by Java and Android apps generated with GeneXus

There is a newer version: 4.7.3
Show newest version
package com.genexus.specific.java;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

import com.genexus.*;
import com.genexus.GXSmartCacheProvider.DataUpdateStatus;
import com.genexus.GXSmartCacheProvider.SmartCacheStatus;
import com.genexus.common.interfaces.IExtensionGXSmartCacheProvider;
import com.genexus.common.interfaces.IGXSmartCacheProvider;
import com.genexus.diagnostics.Log;

public class GXSmartCacheProvider implements IExtensionGXSmartCacheProvider {

	@Override
	public IGXSmartCacheProvider createCache() {
		return new JavaSmartCacheProvider();
	}
	
	public class JavaSmartCacheProvider extends com.genexus.BaseProvider 
	{

		ICacheService updatedTables; 
		SmartCacheStatus status = SmartCacheStatus.Unknown;
		Object syncLock = new Object();
		ConcurrentHashMap> tablesUpdatedInUTL;

		public JavaSmartCacheProvider() {
			super();
			tablesUpdatedInUTL = new ConcurrentHashMap>();
		}
		
		public void invalidateAll()
		{
			if (isEnabled())
			{
				getUpdatedTables().set(CacheFactory.CACHE_SD, FORCED_INVALIDATE, CommonUtil.now(false,false));
			}
		}
		
		public ICacheService getUpdatedTables() {
			if (updatedTables == null) {
				synchronized (syncLock)
				{
					if (updatedTables == null)
						updatedTables = CacheFactory.getInstance();				
				}
			}
			return updatedTables;
		}
		public void invalidate(String item)
		{
			if (isEnabled()) 
				getUpdatedTables().clear(CacheFactory.CACHE_SD, normalizeKey(item));
		}
		public void recordUpdates(int handle)
		{
			if (isEnabled() && tablesUpdatedInUTL.containsKey(handle))
			{
				Vector tablesUpdatedInUTLHandle = getTablesUpdatedInUTL(handle);
				Date  dt = CommonUtil.now(false,false);
				if (!tablesUpdatedInUTLHandle.isEmpty()) {
					ICacheService updTables = getUpdatedTables();
					normalizeKey(tablesUpdatedInUTLHandle);
					if (updTables instanceof ICacheService2) {
						((ICacheService2)updTables).setAll(CacheFactory.CACHE_SD, tablesUpdatedInUTLHandle.toArray(new String[tablesUpdatedInUTLHandle.size()]), Collections.nCopies(tablesUpdatedInUTLHandle.size(), dt).toArray(), 0);
					}else {
						for(String tbl:tablesUpdatedInUTLHandle)
						{
							updTables.set(CacheFactory.CACHE_SD, tbl, dt);
						}
					}
					tablesUpdatedInUTL.remove(handle);
				}
			}
		}
		public DataUpdateStatus CheckDataStatus(String queryId, Date dateLastModified, Date[] dateUpdated_arr)
		{
			try {
				if (isEnabled()){
					ICacheService updTables = getUpdatedTables();
					ConcurrentHashMap> qryTables = queryTables();
					Date dateUpdated = startupDate; // por default los datos son tan viejos como el momento de startup de la app

					dateUpdated_arr[0] = dateUpdated;
					if (!qryTables.containsKey(queryId))      // No hay definicion de tablas para el query -> status desconocido
						return DataUpdateStatus.Unknown;

					Vector qTables = qryTables.get(queryId);
					String[] qTablesArray = qTables.toArray(new String[qTables.size()]);
					List dateUpdates;

					if (updTables instanceof ICacheService2) {
						dateUpdates = ((ICacheService2)updTables).getAll(CacheFactory.CACHE_SD, qTablesArray, Date.class); //Value is null date for non-existing key in cache
					}else{
						dateUpdates = new Vector();
						for(String qTable:qTables)
						{
							if (updTables.containtsKey(CacheFactory.CACHE_SD, qTable)) {
								dateUpdates.add(updTables.get(CacheFactory.CACHE_SD, qTable, Date.class));
							}
						}
					}
					Date maxDateUpdated = MaxDate(dateUpdates);//Obtiene la fecha de modificación mas nueva.
					if (maxDateUpdated!=null && maxDateUpdated.after(dateUpdated))
						dateUpdated = maxDateUpdated;

					dateUpdated_arr[0] = dateUpdated;
					if (dateUpdated.after(dateLastModified) || qTables.size() == 0)    // Si alguna de las tablas del query fueron modificadas o no hay tablas involucradas-> el status de la info es INVALIDO, hay que refrescar
						return DataUpdateStatus.Invalid;
					
					//We've seen situations where SD Client sends: If-Modified-Since: Sun, 20 Apr 2200. Don't know why yet.
					if(dateLastModified != null && dateLastModified.after(new Date()))
						return DataUpdateStatus.Invalid;
					
					return DataUpdateStatus.UpToDate;
				}
			}
			catch (Exception e)
			{
				Log.error("Could not check Request Cache status", "GXSmartCacheProvider", e);
			}		
			return DataUpdateStatus.Unknown;		

		}

		private Date MaxDate(List dates){
			if (dates!=null) {
				while (dates.remove(null)) ; //RemoveNulls
				if (dates.size()>0)
					return Collections.max(dates);
			}
			return null;
		}
		public void discardUpdates(int handle)
		{
			if (isEnabled() && tablesUpdatedInUTL.containsKey(handle))
				tablesUpdatedInUTL.remove(handle);
		}
		public boolean isEnabled() 
		{ 	
			if (status == SmartCacheStatus.Unknown)
			{
				synchronized (syncLock)
				{
					if (status == SmartCacheStatus.Unknown)
						status = (Preferences.getDefaultPreferences().getSMART_CACHING() == true)? SmartCacheStatus.Enabled: SmartCacheStatus.Disabled;						
				}
			}		
			return status == SmartCacheStatus.Enabled;
		}

		@Override
		public void setUpdated(String table, int handle) {
			if (isEnabled()) {
				Vector tablesUpdatedInUTLHandle = getTablesUpdatedInUTL(handle);
				if (!tablesUpdatedInUTLHandle.contains(table))
					tablesUpdatedInUTLHandle.add(table);
			}
		}

		private Vector getTablesUpdatedInUTL(Integer handle){
			if (tablesUpdatedInUTL.containsKey(handle)){
				return tablesUpdatedInUTL.get(handle);
			}
			else {
				Vector tablesUpdated = new Vector();
				tablesUpdatedInUTL.put(handle, tablesUpdated);
				return tablesUpdated;
			}
		}
	}


}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy