| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Portions Copyright 2006 Sun Microsystems, Inc. |
| | | * Portions Copyright 2006-2007 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.extensions; |
| | | |
| | |
| | | import org.opends.server.types.SearchFilter; |
| | | |
| | | import static org.opends.server.config.ConfigConstants.*; |
| | | import static org.opends.server.loggers.Debug.*; |
| | | import static org.opends.server.loggers.debug.DebugLogger.debugCought; |
| | | import static org.opends.server.loggers.debug.DebugLogger.debugEnabled; |
| | | import org.opends.server.types.DebugLogLevel; |
| | | import static org.opends.server.loggers.Error.*; |
| | | import static org.opends.server.messages.ExtensionsMessages.*; |
| | | import static org.opends.server.messages.MessageHandler.*; |
| | |
| | | extends EntryCache |
| | | implements ConfigurableComponent |
| | | { |
| | | /** |
| | | * The fully-qualified name of this class for debugging purposes. |
| | | */ |
| | | private static final String CLASS_NAME = |
| | | "org.opends.server.extensions.FIFOEntryCache"; |
| | | |
| | | |
| | | |
| | |
| | | { |
| | | super(); |
| | | |
| | | assert debugConstructor(CLASS_NAME); |
| | | |
| | | // All initialization should be performed in the initializeEntryCache. |
| | | } |
| | |
| | | public void initializeEntryCache(ConfigEntry configEntry) |
| | | throws ConfigException, InitializationException |
| | | { |
| | | assert debugEnter(CLASS_NAME, "initializeEntryCache", |
| | | String.valueOf(configEntry)); |
| | | |
| | | configEntryDN = configEntry.getDN(); |
| | | |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "initializeEntryCache", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // Log an error message. |
| | | logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.SEVERE_ERROR, |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "initializeEntryCache", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // Log an error message. |
| | | logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.SEVERE_ERROR, |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "initializeEntryCache", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // Log an error message. |
| | | logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.SEVERE_ERROR, |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "initializeEntryCache", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // We couldn't decode this filter. Log a warning and continue. |
| | | logError(ErrorLogCategory.CONFIGURATION, |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "initializeEntryCache", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // Log an error message. |
| | | logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.SEVERE_ERROR, |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "initializeEntryCache", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // We couldn't decode this filter. Log a warning and continue. |
| | | logError(ErrorLogCategory.CONFIGURATION, |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "initializeEntryCache", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // Log an error message. |
| | | logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.SEVERE_ERROR, |
| | |
| | | */ |
| | | public void finalizeEntryCache() |
| | | { |
| | | assert debugEnter(CLASS_NAME, "finalizeEntryCache"); |
| | | |
| | | |
| | | // Release all memory currently in use by this cache. |
| | |
| | | catch (Exception e) |
| | | { |
| | | // This should never happen. |
| | | assert debugException(CLASS_NAME, "finalizeEntryCache", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | } |
| | | finally |
| | | { |
| | |
| | | */ |
| | | public boolean containsEntry(DN entryDN) |
| | | { |
| | | assert debugEnter(CLASS_NAME, "containsEntry", String.valueOf(entryDN)); |
| | | |
| | | // Indicate whether the DN map contains the specified DN. |
| | | return dnMap.containsKey(entryDN); |
| | |
| | | */ |
| | | public Entry getEntry(DN entryDN) |
| | | { |
| | | assert debugEnter(CLASS_NAME, "getEntry", String.valueOf(entryDN)); |
| | | |
| | | |
| | | // Simply return the entry from the DN map. |
| | |
| | | */ |
| | | public long getEntryID(DN entryDN) |
| | | { |
| | | assert debugEnter(CLASS_NAME, "getEntryID", String.valueOf(entryDN)); |
| | | |
| | | // Simply return the ID from the DN map. |
| | | CacheEntry e = dnMap.get(entryDN); |
| | |
| | | */ |
| | | public Entry getEntry(DN entryDN, LockType lockType, List<Lock> lockList) |
| | | { |
| | | assert debugEnter(CLASS_NAME, "getEntry", String.valueOf(entryDN), |
| | | String.valueOf(lockType), "java.util.List<Lock>"); |
| | | |
| | | |
| | | // Get the entry from the DN map if it is present. If not, then return |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "getEntry", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // The attempt to add the lock to the list failed, so we need to |
| | | // release the lock and return null. |
| | |
| | | } |
| | | catch (Exception e2) |
| | | { |
| | | assert debugException(CLASS_NAME, "getEntry", e2); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e2); |
| | | } |
| | | } |
| | | |
| | | return null; |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "getEntry", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // The attempt to add the lock to the list failed, so we need to |
| | | // release the lock and return null. |
| | |
| | | } |
| | | catch (Exception e2) |
| | | { |
| | | assert debugException(CLASS_NAME, "getEntry", e2); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e2); |
| | | } |
| | | } |
| | | |
| | | return null; |
| | |
| | | public Entry getEntry(Backend backend, long entryID, LockType lockType, |
| | | List<Lock> lockList) |
| | | { |
| | | assert debugEnter(CLASS_NAME, "getEntry", String.valueOf(backend), |
| | | String.valueOf(entryID), String.valueOf(lockType), |
| | | "java.util.List<Lock>"); |
| | | |
| | | // Get the hash map for the provided backend. If it isn't present, then |
| | | // return null. |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "getEntry", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // The attempt to add the lock to the list failed, so we need to |
| | | // release the lock and return null. |
| | |
| | | } |
| | | catch (Exception e2) |
| | | { |
| | | assert debugException(CLASS_NAME, "getEntry", e2); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e2); |
| | | } |
| | | } |
| | | |
| | | return null; |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "getEntry", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // The attempt to add the lock to the list failed, so we need to |
| | | // release the lock and return null. |
| | |
| | | } |
| | | catch (Exception e2) |
| | | { |
| | | assert debugException(CLASS_NAME, "getEntry", e2); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e2); |
| | | } |
| | | } |
| | | |
| | | return null; |
| | |
| | | */ |
| | | public void putEntry(Entry entry, Backend backend, long entryID) |
| | | { |
| | | assert debugEnter(CLASS_NAME, "putEntry", String.valueOf(entry), |
| | | String.valueOf(backend), String.valueOf(entryID)); |
| | | |
| | | |
| | | // If there is a set of exclude filters, then make sure that the provided |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "putEntry", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // This shouldn't happen, but if it does then we can't be sure whether |
| | | // the entry should be excluded, so we will by default. |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "putEntry", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // This shouldn't happen, but if it does, then just ignore it. |
| | | } |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "putEntry", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | return; |
| | | } |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "putEntry", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | return; |
| | | } |
| | |
| | | */ |
| | | public boolean putEntryIfAbsent(Entry entry, Backend backend, long entryID) |
| | | { |
| | | assert debugEnter(CLASS_NAME, "putEntryIfAbsent", String.valueOf(entry), |
| | | String.valueOf(backend), String.valueOf(entryID)); |
| | | |
| | | |
| | | // If there is a set of exclude filters, then make sure that the provided |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "putEntry", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // This shouldn't happen, but if it does then we can't be sure whether |
| | | // the entry should be excluded, so we will by default. |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "putEntry", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // This shouldn't happen, but if it does, then just ignore it. |
| | | } |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "putEntry", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // We can't rule out the possibility of a conflict, so return false. |
| | | return false; |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "putEntry", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // We can't be sure there wasn't a conflict, so return false. |
| | | return false; |
| | |
| | | */ |
| | | public void removeEntry(DN entryDN) |
| | | { |
| | | assert debugEnter(CLASS_NAME, "removeEntry", String.valueOf(entryDN)); |
| | | |
| | | |
| | | // Acquire the lock on the cache. We should not return until the entry is |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "removeEntry", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // This shouldn't happen, but there's not much that we can do if it does. |
| | | } |
| | |
| | | */ |
| | | public void clear() |
| | | { |
| | | assert debugEnter(CLASS_NAME, "clear"); |
| | | |
| | | // Acquire a lock on the cache. We should not return until the cache has |
| | | // been cleared, so we will block until we can obtain the lock. |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "clear", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // This shouldn't happen, but there's not much that we can do if it does. |
| | | } |
| | |
| | | */ |
| | | public void clearBackend(Backend backend) |
| | | { |
| | | assert debugEnter(CLASS_NAME, "clearBackend", String.valueOf(backend)); |
| | | |
| | | // Acquire a lock on the cache. We should not return until the cache has |
| | | // been cleared, so we will block until we can obtain the lock. |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "clearBackend", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // This shouldn't happen, but there's not much that we can do if it does. |
| | | } |
| | |
| | | */ |
| | | public void clearSubtree(DN baseDN) |
| | | { |
| | | assert debugEnter(CLASS_NAME, "clearSubtree", String.valueOf(baseDN)); |
| | | |
| | | |
| | | // Determine which backend should be used for the provided base DN. If |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "clearBackend", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // This shouldn't happen, but there's not much that we can do if it does. |
| | | } |
| | |
| | | */ |
| | | private void clearSubtree(DN baseDN, Backend backend) |
| | | { |
| | | assert debugEnter(CLASS_NAME, "clearSubtree", String.valueOf(baseDN), |
| | | String.valueOf(backend)); |
| | | |
| | | |
| | | // See if there are any entries for the provided backend in the cache. If |
| | |
| | | } |
| | | |
| | | entriesExamined++; |
| | | if ((entriesExamined % 1000) == 0) |
| | | if ((entriesExamined % 1000) == 0) |
| | | { |
| | | cacheLock.unlock(); |
| | | Thread.currentThread().yield(); |
| | |
| | | */ |
| | | public void handleLowMemory() |
| | | { |
| | | assert debugEnter(CLASS_NAME, "handleLowMemory"); |
| | | |
| | | |
| | | // Grab the lock on the cache and wait until we have it. |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "handleLowMemory", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // This shouldn't happen, but there's not much that we can do if it does. |
| | | } |
| | |
| | | */ |
| | | public DN getConfigurableComponentEntryDN() |
| | | { |
| | | assert debugEnter(CLASS_NAME, "getConfigurableComponentEntryDN"); |
| | | |
| | | return configEntryDN; |
| | | } |
| | |
| | | */ |
| | | public List<ConfigAttribute> getConfigurationAttributes() |
| | | { |
| | | assert debugEnter(CLASS_NAME, "getConfigurationAttributes"); |
| | | |
| | | LinkedList<ConfigAttribute> attrList = new LinkedList<ConfigAttribute>(); |
| | | |
| | |
| | | public boolean hasAcceptableConfiguration(ConfigEntry configEntry, |
| | | List<String> unacceptableReasons) |
| | | { |
| | | assert debugEnter(CLASS_NAME, "hasAcceptableConfiguration", |
| | | String.valueOf(configEntry), "java.util.List<String>"); |
| | | |
| | | |
| | | // Start out assuming that the configuration is valid. |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "hasAcceptableConfiguration", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // An error occurred, so the provided value must not be valid. |
| | | msgID = MSGID_FIFOCACHE_INVALID_MAX_MEMORY_PCT; |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "initializeEntryCache", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // An error occurred, so the provided value must not be valid. |
| | | msgID = MSGID_FIFOCACHE_INVALID_MAX_ENTRIES; |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "initializeEntryCache", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // An error occurred, so the provided value must not be valid. |
| | | msgID = MSGID_FIFOCACHE_INVALID_LOCK_TIMEOUT; |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "initializeEntryCache", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // We couldn't decode this filter, so it isn't valid. |
| | | msgID = MSGID_FIFOCACHE_INVALID_INCLUDE_FILTER; |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "initializeEntryCache", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // An error occurred, so the provided value must not be valid. |
| | | msgID = MSGID_FIFOCACHE_INVALID_INCLUDE_FILTERS; |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "initializeEntryCache", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // We couldn't decode this filter, so it isn't valid. |
| | | msgID = MSGID_FIFOCACHE_INVALID_EXCLUDE_FILTER; |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "initializeEntryCache", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // An error occurred, so the provided value must not be valid. |
| | | msgID = MSGID_FIFOCACHE_INVALID_EXCLUDE_FILTERS; |
| | |
| | | public ConfigChangeResult applyNewConfiguration(ConfigEntry configEntry, |
| | | boolean detailedResults) |
| | | { |
| | | assert debugEnter(CLASS_NAME, "applyNewConfiguration", |
| | | String.valueOf(configEntry), |
| | | String.valueOf(detailedResults)); |
| | | |
| | | |
| | | // Create a set of variables to use for the result. |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "applyNewConfiguration", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // An error occurred, so the provided value must not be valid. |
| | | msgID = MSGID_FIFOCACHE_INVALID_MAX_MEMORY_PCT; |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "applyNewConfiguration", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // An error occurred, so the provided value must not be valid. |
| | | msgID = MSGID_FIFOCACHE_INVALID_MAX_ENTRIES; |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "applyNewConfiguration", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // An error occurred, so the provided value must not be valid. |
| | | msgID = MSGID_FIFOCACHE_INVALID_LOCK_TIMEOUT; |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "applyNewConfiguration", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // We couldn't decode this filter, so it isn't valid. |
| | | msgID = MSGID_FIFOCACHE_INVALID_INCLUDE_FILTER; |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "applyNewConfiguration", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // An error occurred, so the provided value must not be valid. |
| | | msgID = MSGID_FIFOCACHE_INVALID_INCLUDE_FILTERS; |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "applyNewConfiguration", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // We couldn't decode this filter, so it isn't valid. |
| | | msgID = MSGID_FIFOCACHE_INVALID_EXCLUDE_FILTER; |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | assert debugException(CLASS_NAME, "applyNewConfiguration", e); |
| | | if (debugEnabled()) |
| | | { |
| | | debugCought(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // An error occurred, so the provided value must not be valid. |
| | | msgID = MSGID_FIFOCACHE_INVALID_EXCLUDE_FILTERS; |