details: https://code.openbravo.com/erp/devel/pi/rev/a67a1b567591 changeset: 28553:a67a1b567591 user: Carlos Aristu <carlos.aristu <at> openbravo.com> date: Fri Jan 29 13:34:12 2016 +0100 summary: fixes issue 32039: Add generic mechanism to have multiple cached preferences
The new CachedPreference class can be used to keep the value of a preference defined at system level. The value of the 'Allow Unpaged Datasource Manual Request' preference is already handled by this class. So the UnpagedRequestCachedPreference is not needed anymore. diffstat: modules/org.openbravo.client.application/src/org/openbravo/client/application/CachedPreference.java | 139 ++++++++++ modules/org.openbravo.client.application/src/org/openbravo/client/application/event/PreferenceEventHandler.java | 28 +- modules/org.openbravo.service.json/src/org/openbravo/service/json/DefaultJsonDataService.java | 10 +- modules/org.openbravo.service.json/src/org/openbravo/service/json/UnpagedRequestCachedPreference.java | 94 ------ 4 files changed, 158 insertions(+), 113 deletions(-) diffs (truncated from 364 to 300 lines): diff -r cc28a29cb724 -r a67a1b567591 modules/org.openbravo.client.application/src/org/openbravo/client/application/CachedPreference.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/org.openbravo.client.application/src/org/openbravo/client/application/CachedPreference.java Fri Jan 29 13:34:12 2016 +0100 @@ -0,0 +1,139 @@ +/* + ************************************************************************* + * The contents of this file are subject to the Openbravo Public License + * Version 1.1 (the "License"), being the Mozilla Public License + * Version 1.1 with a permitted attribution clause; you may not use this + * file except in compliance with the License. You may obtain a copy of + * the License at http://www.openbravo.com/legal/license.html + * 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. + * The Original Code is Openbravo ERP. + * The Initial Developer of the Original Code is Openbravo SLU + * All portions are Copyright (C) 2016 Openbravo SLU + * All Rights Reserved. + * Contributor(s): ______________________________________. + ************************************************************************ + */ +package org.openbravo.client.application; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.enterprise.context.ApplicationScoped; + +import org.openbravo.dal.core.OBContext; +import org.openbravo.dal.service.OBDal; +import org.openbravo.erpCommon.businessUtility.Preferences; +import org.openbravo.erpCommon.utility.PropertyException; +import org.openbravo.model.ad.system.Client; +import org.openbravo.model.common.enterprise.Organization; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class is used as a singleton to keep the value of some preferences in cache during the + * application life cycle, avoiding the time spent to compute the preference value. The preference + * values that can be cached by this class are those defined at System level. + * + * This class it is also used by the + * {@link org.openbravo.client.application.event.PreferenceEventHandler} class to detect changes in + * the cached preferences values, and it that case it invalidates the stored value. This way the + * next time it is requested, the current value will be retrieved from database again. + * + * This mechanism for automatic refresh the preference value, only works on environments with a + * single JVM. In case of Tomcat clustering environments (multiple JVM) it will be necessary to + * restart Tomcat to retrieve the new value of the preference in every JVM. + * + */ +@ApplicationScoped +public class CachedPreference { + private static final Logger log = LoggerFactory.getLogger(CachedPreference.class); + private List<String> propertyList = new ArrayList<String>( + Arrays.asList("OBJSON_AllowUnpagedDatasourceManualRequest")); + private Map<String, String> cachedPreference = new HashMap<String, String>(); + + /** + * It returns a String with the value of the preference whose related property name is entered as + * parameter. In case the value is not stored in cache, then the value will be retrieved from + * database. + * + * @param propertyName + * The name of the property related to the preference + * + * @return A String with the value of the cached preference + */ + public String getPreferenceValue(String propertyName) { + long t = System.nanoTime(); + if (!cachedPreference.containsKey(propertyName)) { + try { + OBContext.setAdminMode(false); + Client systemClient = OBDal.getInstance().get(Client.class, "0"); + Organization asterisk = OBDal.getInstance().get(Organization.class, "0"); + String value = Preferences.getPreferenceValue(propertyName, true, systemClient, asterisk, + null, null, null); + setPreferenceValue(propertyName, value); + } catch (PropertyException ignore) { + // Ignore the exception, caused because the preference was not found + setPreferenceValue(propertyName, null); + } finally { + OBContext.restorePreviousMode(); + } + } + log.debug("preference value retrieved in {} ns", (System.nanoTime() - t)); + return cachedPreference.get(propertyName); + } + + /** + * Checks if the preference related to the property name entered as parameter is contained in the + * list of cached preferences. + * + * @param propertyName + * The name of the property related to the preference + * @return true if the preference related to the property name is a cached preference, false + * otherwise + */ + public boolean isCachedPreference(String propertyName) { + return propertyList.contains(propertyName); + } + + /** + * Sets the cached value of the preference. This method is defined as synchronized in order to + * avoid concurrency problems. + * + * @param propertyName + * The name of the property related to the preference + * @param preferenceValue + * String with the value assigned to the preference + */ + public synchronized void setPreferenceValue(String propertyName, String preferenceValue) { + this.cachedPreference.put(propertyName, preferenceValue); + } + + /** + * Invalidates the cached value of the preference. This method is defined as synchronized in order + * to avoid concurrency problems. + * + * @param propertyName + * The name of the property related to the preference + */ + public synchronized void invalidatePreferenceValue(String propertyName) { + this.cachedPreference.remove(propertyName); + } + + /** + * Adds a new preference into the set of preferences whose value is stored in cache. + * + * @param propertyName + * The name of the property related to the preference to be cached + */ + public void addCachedPreference(String propertyName) { + if (!isCachedPreference(propertyName)) { + propertyList.add(propertyName); + } + } +} diff -r cc28a29cb724 -r a67a1b567591 modules/org.openbravo.client.application/src/org/openbravo/client/application/event/PreferenceEventHandler.java --- a/modules/org.openbravo.client.application/src/org/openbravo/client/application/event/PreferenceEventHandler.java Fri Jan 29 12:56:36 2016 +0100 +++ b/modules/org.openbravo.client.application/src/org/openbravo/client/application/event/PreferenceEventHandler.java Fri Jan 29 13:34:12 2016 +0100 @@ -11,7 +11,7 @@ * under the License. * The Original Code is Openbravo ERP. * The Initial Developer of the Original Code is Openbravo SLU - * All portions are Copyright (C) 2015 Openbravo SLU + * All portions are Copyright (C) 2015-2016 Openbravo SLU * All Rights Reserved. * Contributor(s): ______________________________________. ************************************************************************ @@ -25,20 +25,16 @@ import org.apache.log4j.Logger; import org.openbravo.base.model.Entity; import org.openbravo.base.model.ModelProvider; +import org.openbravo.client.application.CachedPreference; import org.openbravo.client.kernel.event.EntityDeleteEvent; import org.openbravo.client.kernel.event.EntityNewEvent; import org.openbravo.client.kernel.event.EntityPersistenceEventObserver; import org.openbravo.client.kernel.event.EntityUpdateEvent; import org.openbravo.model.ad.domain.Preference; -import org.openbravo.service.json.UnpagedRequestCachedPreference; /** * Listens to delete, update and save events for the {@link Preference} entity. If it detects a - * change in the 'OBJSON_AllowUnpagedDatasourceManualRequest' preference it invalidates its cached - * value by setting it to null. - * - * {@link "https://issues.openbravo.com/view.php?id=30204"} - * + * change in any of the cached preferences it invalidates its cached value. */ public class PreferenceEventHandler extends EntityPersistenceEventObserver { @@ -46,7 +42,7 @@ .getEntity(Preference.ENTITY_NAME) }; protected Logger logger = Logger.getLogger(this.getClass()); @Inject - private UnpagedRequestCachedPreference unpagedRequestPreference; + private CachedPreference cachedPreference; @Override protected Entity[] getObservedEntities() { @@ -58,9 +54,7 @@ return; } final Preference preference = (Preference) event.getTargetInstance(); - if (unpagedRequestPreference.getProperty().equals(preference.getProperty())) { - unpagedRequestPreference.setPreferenceValue(null); - } + invalidateCachedPreferenceValue(preference.getProperty()); } public void onUpdate(@Observes EntityUpdateEvent event) { @@ -68,9 +62,7 @@ return; } final Preference preference = (Preference) event.getTargetInstance(); - if (unpagedRequestPreference.getProperty().equals(preference.getProperty())) { - unpagedRequestPreference.setPreferenceValue(null); - } + invalidateCachedPreferenceValue(preference.getProperty()); } public void onDelete(@Observes EntityDeleteEvent event) { @@ -78,8 +70,12 @@ return; } final Preference preference = (Preference) event.getTargetInstance(); - if (unpagedRequestPreference.getProperty().equals(preference.getProperty())) { - unpagedRequestPreference.setPreferenceValue(null); + invalidateCachedPreferenceValue(preference.getProperty()); + } + + private void invalidateCachedPreferenceValue(String property) { + if (cachedPreference.isCachedPreference(property)) { + cachedPreference.invalidatePreferenceValue(property); } } } diff -r cc28a29cb724 -r a67a1b567591 modules/org.openbravo.service.json/src/org/openbravo/service/json/DefaultJsonDataService.java --- a/modules/org.openbravo.service.json/src/org/openbravo/service/json/DefaultJsonDataService.java Fri Jan 29 12:56:36 2016 +0100 +++ b/modules/org.openbravo.service.json/src/org/openbravo/service/json/DefaultJsonDataService.java Fri Jan 29 13:34:12 2016 +0100 @@ -11,7 +11,7 @@ * under the License. * The Original Code is Openbravo ERP. * The Initial Developer of the Original Code is Openbravo SLU - * All portions are Copyright (C) 2009-2015 Openbravo SLU + * All portions are Copyright (C) 2009-2016 Openbravo SLU * All Rights Reserved. * Contributor(s): ______________________________________. ************************************************************************ @@ -42,6 +42,7 @@ import org.openbravo.base.structure.BaseOBObject; import org.openbravo.base.util.Check; import org.openbravo.base.weld.WeldUtils; +import org.openbravo.client.application.CachedPreference; import org.openbravo.dal.core.DalUtil; import org.openbravo.dal.core.OBContext; import org.openbravo.dal.service.OBDal; @@ -73,8 +74,10 @@ private static final String ADD_FLAG = "_doingAdd"; + private static final String ALLOW_UNPAGED_DS_MANUAL_REQUEST = "OBJSON_AllowUnpagedDatasourceManualRequest"; + @Inject - private UnpagedRequestCachedPreference unpagedRequestPreference; + private CachedPreference cachedPreference; private static DefaultJsonDataService instance = WeldUtils .getInstanceFromStaticBeanManager(DefaultJsonDataService.class); @@ -473,7 +476,8 @@ // for standard tab and selector datasources pagination is mandatory throw new OBException(OBMessageUtils.messageBD("OBJSON_NoPagedFetch")); - } else if (!"Y".equals(unpagedRequestPreference.getPreferenceValue()) && !isWsCall) { + } else if (!"Y".equals(cachedPreference.getPreferenceValue(ALLOW_UNPAGED_DS_MANUAL_REQUEST)) + && !isWsCall) { throw new OBException(OBMessageUtils.messageBD("OBJSON_NoPagedFetchManual")); } } diff -r cc28a29cb724 -r a67a1b567591 modules/org.openbravo.service.json/src/org/openbravo/service/json/UnpagedRequestCachedPreference.java --- a/modules/org.openbravo.service.json/src/org/openbravo/service/json/UnpagedRequestCachedPreference.java Fri Jan 29 12:56:36 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,94 +0,0 @@ -/* - ************************************************************************* - * The contents of this file are subject to the Openbravo Public License - * Version 1.1 (the "License"), being the Mozilla Public License - * Version 1.1 with a permitted attribution clause; you may not use this - * file except in compliance with the License. You may obtain a copy of - * the License at http://www.openbravo.com/legal/license.html - * 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. - * The Original Code is Openbravo ERP. - * The Initial Developer of the Original Code is Openbravo SLU - * All portions are Copyright (C) 2015 Openbravo SLU - * All Rights Reserved. - * Contributor(s): ______________________________________. - ************************************************************************ - */ -package org.openbravo.service.json; - -import javax.enterprise.context.ApplicationScoped; - -import org.openbravo.dal.core.OBContext; -import org.openbravo.dal.service.OBDal; -import org.openbravo.erpCommon.businessUtility.Preferences; -import org.openbravo.erpCommon.utility.PropertyException; -import org.openbravo.model.ad.system.Client; -import org.openbravo.model.common.enterprise.Organization; - -/** ------------------------------------------------------------------------------ Site24x7 APM Insight: Get Deep Visibility into Application Performance APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month Monitor end-to-end web transactions and take corrective actions now Troubleshoot faster and improve end-user experience. Signup Now! http://pubads.g.doubleclick.net/gampad/clk?id=267308311&iu=/4140 _______________________________________________ Openbravo-commits mailing list Openbravo-commits@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openbravo-commits