/* * � Copyright IBM Corp. 2010 * * 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.ibm.xsp.extlib.social.impl; import java.util.Map; import java.util.Set; import javax.faces.context.ExternalContext; import javax.faces.context.FacesContext; import com.ibm.commons.util.StringUtil; import com.ibm.commons.util.SystemCache; import com.ibm.xsp.context.FacesContextEx; import com.ibm.xsp.extlib.social.impl.ResourceImpl.Properties; import com.ibm.xsp.extlib.util.ExtLibUtil; import com.ibm.xsp.util.TypedUtil; /** * People data provider. * <p> * Basic implementation of a people provider. * </p> * @author Philippe Riand */ public abstract class AbstractResourceProvider implements ResourceDataProvider { private int cacheScope; private int cacheSize; public AbstractResourceProvider() { FacesContextEx context = FacesContextEx.getCurrentInstance(); this.cacheScope = readPropertyCacheScope(context, getCacheScopeProperty(), getDefaultCacheScope()); // $NON-NLS-1$ this.cacheSize = readPropertyInt(context, getCacheSizeProperty(), getDefaultCacheSize()); } protected String getCacheScopeProperty() { return null; } protected String getDefaultCacheScope() { return "application"; // $NON-NLS-1$ } protected String getCacheSizeProperty() { return null; } protected int getDefaultCacheSize() { return 100; } public boolean isDefaultProvider() { // We make the application loaded class default providers. return ExtLibUtil.isApplicationClass(getClass()); } public String getName() { return getClass().getName(); } public void enumerateProperties(Set<String> propNames) { } protected int readPropertyCacheScope(FacesContextEx context, String name, String def) { String s = readProperty(context, name, def); if(StringUtil.equals(s, "none")) { // $NON-NLS-1$ return SCOPE_NONE; } else if(StringUtil.equals(s, "session")) { // $NON-NLS-1$ return SCOPE_SESSION; } else if(StringUtil.equals(s, "global")) { // $NON-NLS-1$ return SCOPE_GLOBAL; } else if(StringUtil.equals(s, "request")) { // $NON-NLS-1$ return SCOPE_REQUEST; } return SCOPE_APPLICATION; } protected String readProperty(FacesContextEx context, String name, String def) { if(StringUtil.isNotEmpty(name)) { String s = context.getProperty(name); if(StringUtil.isNotEmpty(s)) { return s; } } return def; } protected int readPropertyInt(FacesContextEx context, String name, int def) { if(StringUtil.isNotEmpty(name)) { String s = context.getProperty(name); if(StringUtil.isNotEmpty(s)) { try { return Integer.parseInt(s); } catch(Exception e) {} // Use the default value for a bad integer } } return def; } public int getCacheScope() { return cacheScope; } public int getCacheSize() { return cacheSize; } public int getWeight() { return WEIGHT_HIGH; } // ====================================================================== // Utility function to cache property values // This is not meant to be used directly by the XPages developer but by // the user bean data provider developer. // ====================================================================== public static final String CACHE_KEY = "xsp.extlib.social.cache"; // $NON-NLS-1$ private static SystemCache globalCache; /** * Get or create the properties object. */ public Properties getProperties(String id, Class<?> clazz) { SystemCache c = getCache(false); if(c!=null) { // Look for the properties in the list for(Properties prop=(Properties)c.get(id); prop!=null; prop=prop.next) { if(prop.getClass()==clazz) { return prop; } } } return null; } public void addProperties(String id, Properties props) { SystemCache c = getCache(true); if(c!=null) { props.next = (Properties)c.get(id); c.put(id,props); } } public Object getSyncObject() { return this; } protected SystemCache getCache(boolean create) { int scope = getCacheScope(); switch(scope) { case ResourceDataProvider.SCOPE_NONE: { return null; } case ResourceDataProvider.SCOPE_GLOBAL: { synchronized (AbstractResourceProvider.class) { if(globalCache==null && create) { globalCache = createCache(scope); } return globalCache; } } case ResourceDataProvider.SCOPE_APPLICATION: { Map<String, Object> map = getApplicationMap(FacesContext.getCurrentInstance().getExternalContext()); SystemCache c = (SystemCache)map.get(CACHE_KEY); if(c==null && create) { synchronized(map) { c = (SystemCache)map.get(CACHE_KEY); if(c==null) { c = createCache(scope); if(c!=null) { map.put(CACHE_KEY,c); } } } } return c; } case ResourceDataProvider.SCOPE_SESSION: { Map<String, Object> map = TypedUtil.getSessionMap(FacesContext.getCurrentInstance().getExternalContext()); SystemCache c = (SystemCache)map.get(CACHE_KEY); if(c==null && create) { synchronized(map) { c = (SystemCache)map.get(CACHE_KEY); if(c==null) { c = createCache(scope); if(c!=null) { map.put(CACHE_KEY,c); } } } } return c; } case ResourceDataProvider.SCOPE_REQUEST: { Map<String, Object> map = TypedUtil.getRequestMap(FacesContext.getCurrentInstance().getExternalContext()); SystemCache c = (SystemCache)map.get(CACHE_KEY); if(c==null && create) { synchronized(map) { c = (SystemCache)map.get(CACHE_KEY); if(c==null) { c = createCache(scope); if(c!=null) { map.put(CACHE_KEY,c); } } } } return c; } } return null; } protected SystemCache createCache(int scope) { int size = getCacheSize(); return new SystemCache("Social Resource Cache",size); // $NON-NLS-1$ } public void clearCache() { int scope = getCacheScope(); switch(scope) { case ResourceDataProvider.SCOPE_NONE: { return; } case ResourceDataProvider.SCOPE_GLOBAL: { synchronized (AbstractResourceProvider.class) { globalCache = null; } return; } case ResourceDataProvider.SCOPE_APPLICATION: { Map<String, Object> map = getApplicationMap(FacesContext.getCurrentInstance().getExternalContext()); synchronized(map) { map.remove(CACHE_KEY); } return; } case ResourceDataProvider.SCOPE_SESSION: { Map<String, Object> map = TypedUtil.getSessionMap(FacesContext.getCurrentInstance().getExternalContext()); synchronized(map) { map.remove(CACHE_KEY); } return; } case ResourceDataProvider.SCOPE_REQUEST: { Map<String, Object> map = TypedUtil.getRequestMap(FacesContext.getCurrentInstance().getExternalContext()); synchronized(map) { map.remove(CACHE_KEY); } return; } } } public void clearCache(String id) { if(StringUtil.isEmpty(id)) { clearCache(); return; } int scope = getCacheScope(); switch(scope) { case ResourceDataProvider.SCOPE_NONE: { return; } case ResourceDataProvider.SCOPE_GLOBAL: { if(globalCache!=null) { globalCache.remove(id); } return; } case ResourceDataProvider.SCOPE_APPLICATION: { Map<String, Object> map = getApplicationMap(FacesContext.getCurrentInstance().getExternalContext()); SystemCache c = (SystemCache)map.get(CACHE_KEY); if(c==null) { synchronized(map) { map.remove(CACHE_KEY); } } return; } case ResourceDataProvider.SCOPE_SESSION: { Map<String, Object> map = TypedUtil.getSessionMap(FacesContext.getCurrentInstance().getExternalContext()); SystemCache c = (SystemCache)map.get(CACHE_KEY); if(c==null) { synchronized(map) { map.remove(CACHE_KEY); } } return; } case ResourceDataProvider.SCOPE_REQUEST: { Map<String, Object> map = TypedUtil.getRequestMap(FacesContext.getCurrentInstance().getExternalContext()); SystemCache c = (SystemCache)map.get(CACHE_KEY); if(c==null) { synchronized(map) { map.remove(CACHE_KEY); } } return; } } } @SuppressWarnings("unchecked") //$NON-NLS-1$ private static Map<String, Object> getApplicationMap(ExternalContext externalContext) { return (Map<String, Object>)externalContext.getApplicationMap(); } }