Return-Path: X-Original-To: apmail-geode-commits-archive@minotaur.apache.org Delivered-To: apmail-geode-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id B15A210108 for ; Tue, 28 Apr 2015 21:43:47 +0000 (UTC) Received: (qmail 79511 invoked by uid 500); 28 Apr 2015 21:43:47 -0000 Delivered-To: apmail-geode-commits-archive@geode.apache.org Received: (qmail 79486 invoked by uid 500); 28 Apr 2015 21:43:47 -0000 Mailing-List: contact commits-help@geode.incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@geode.incubator.apache.org Delivered-To: mailing list commits@geode.incubator.apache.org Received: (qmail 79477 invoked by uid 99); 28 Apr 2015 21:43:47 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 28 Apr 2015 21:43:47 +0000 X-ASF-Spam-Status: No, hits=-0.0 required=5.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: domain of root@apache.org designates 54.76.25.247 as permitted sender) Received: from [54.76.25.247] (HELO mx1-eu-west.apache.org) (54.76.25.247) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 28 Apr 2015 21:42:32 +0000 Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx1-eu-west.apache.org (ASF Mail Server at mx1-eu-west.apache.org) with SMTP id 74FFD2AA71 for ; Tue, 28 Apr 2015 21:41:25 +0000 (UTC) Received: (qmail 68656 invoked by uid 99); 28 Apr 2015 21:40:06 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 28 Apr 2015 21:40:06 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 7ED33E32B8; Tue, 28 Apr 2015 21:40:06 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: rvs@apache.org To: commits@geode.incubator.apache.org Date: Tue, 28 Apr 2015 21:40:32 -0000 Message-Id: <9030374abdaf423bbed0a0386a2f73f9@git.apache.org> In-Reply-To: <9e9818e7b1254a349e64bb9fdafc5503@git.apache.org> References: <9e9818e7b1254a349e64bb9fdafc5503@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [27/51] [partial] incubator-geode git commit: Init X-Virus-Checked: Checked by ClamAV on apache.org http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/AttributesFactory.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/AttributesFactory.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/AttributesFactory.java new file mode 100644 index 0000000..9f6984d --- /dev/null +++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/AttributesFactory.java @@ -0,0 +1,1999 @@ +/*========================================================================= + * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved. + * This product is protected by U.S. and international copyright + * and intellectual property laws. Pivotal products are covered by + * more patents listed at http://www.pivotal.io/patents. + *========================================================================= + */ + +package com.gemstone.gemfire.cache; + +import java.io.File; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArraySet; + +import com.gemstone.gemfire.cache.client.ClientCache; +import com.gemstone.gemfire.cache.client.ClientRegionShortcut; +import com.gemstone.gemfire.cache.client.PoolManager; +import com.gemstone.gemfire.compression.Compressor; +import com.gemstone.gemfire.internal.cache.AbstractRegion; +import com.gemstone.gemfire.internal.cache.DiskStoreFactoryImpl; +import com.gemstone.gemfire.internal.cache.DiskWriteAttributesImpl; +import com.gemstone.gemfire.internal.cache.EvictionAttributesImpl; +import com.gemstone.gemfire.internal.cache.GemFireCacheImpl; +import com.gemstone.gemfire.internal.cache.PartitionAttributesImpl; +import com.gemstone.gemfire.internal.cache.PartitionedRegionHelper; +import com.gemstone.gemfire.internal.cache.UserSpecifiedRegionAttributes; +import com.gemstone.gemfire.internal.cache.xmlcache.RegionAttributesCreation; +import com.gemstone.gemfire.internal.i18n.LocalizedStrings; + +/** Creates instances of {@link RegionAttributes}. An AttributesFactory + * instance maintains state for creating RegionAttributes instances. + * The setter methods are used to change the settings that will be used for + * creating the next attributes instance with the {@link #create} + * method. If you create a factory with the default constructor, then the + * factory is set up to create attributes with all default settings. You can + * also create a factory by providing a RegionAttributes, which + * will set up the new factory with the settings provided in that attributes + * instance. + * + *

Once a RegionAttributes is created, it can only be modified + * after it has been used to create a Region, and then only by + * using an {@link AttributesMutator} obtained from the region. + * + *

Attributes

+ *

Callbacks

+ *
+ *
{@link CacheLoader} [default: null, meaning no loader]
+ *
User-implemented plug-in for loading data on cache misses.
+ * {@link #setCacheLoader} {@link RegionAttributes#getCacheLoader} + * {@link AttributesMutator#setCacheLoader}
+ * + *
{@link CacheWriter} [default: null, meaning no writer]
+ *
User-implemented plug-in for intercepting cache modifications, e.g. + * for writing to an external data source.
+ * {@link #setCacheWriter} {@link RegionAttributes#getCacheWriter} + * {@link AttributesMutator#setCacheWriter}
+ * + *
{@link CacheListener} [default: null, meaning no listener ]
+ *
User-implemented plug-in for receiving and handling cache related events.
+ * {@link #addCacheListener} {@link #initCacheListeners} + * {@link #initCacheListeners} + * {@link RegionAttributes#getCacheListeners} + * {@link AttributesMutator#initCacheListeners} + * {@link AttributesMutator#addCacheListener} + * {@link AttributesMutator#removeCacheListener}
+ *
+ *

Expiration

+ *
+ *
RegionTimeToLive [default: no expiration]
+ *
Expiration configuration for the entire region based on the + * {@link CacheStatistics#getLastModifiedTime lastModifiedTime}.
+ * {@link #setRegionTimeToLive} {@link RegionAttributes#getRegionTimeToLive} + * {@link AttributesMutator#setRegionTimeToLive}
+ * + *
RegionIdleTimeout [default: no expiration]
+ *
Expiration configuration for the entire region based on the + * {@link CacheStatistics#getLastAccessedTime lastAccessedTime}.
+ * {@link #setRegionIdleTimeout} {@link RegionAttributes#getRegionIdleTimeout} + * {@link AttributesMutator#setRegionIdleTimeout}
+ * + *
EntryTimeToLive [default: no expiration]
+ *
Expiration configuration for individual entries based on the + * {@link CacheStatistics#getLastModifiedTime lastModifiedTime}.
+ * {@link #setEntryTimeToLive} {@link RegionAttributes#getEntryTimeToLive} + * {@link AttributesMutator#setEntryTimeToLive}
+ * + *
EntryIdleTimeout [default: no expiration]
+ *
Expiration configuration for individual entries based on the + * {@link CacheStatistics#getLastAccessedTime lastAccessedTime}.
+ * {@link #setEntryIdleTimeout} {@link RegionAttributes#getEntryIdleTimeout} + * {@link AttributesMutator#setEntryIdleTimeout}
+ *
+ *

Distribution

+ *
+ *
{@link Scope}[default: {@link Scope#DISTRIBUTED_NO_ACK}] + *
+ *
Properties of distribution for the region, including whether it is + * distributed at all, whether acknowledgements are required, and whether + * distributed synchronization is required.
+ * {@link #setScope} {@link RegionAttributes#getScope}
+ * + *
EarlyAck [default: false]
+ *
Whether or not acks required by Scope.DISTRIBUTED_ACK + * are sent after an operation is processed. If true + * then remote caches will ACK before processing an operation sent + * by the cache that has set earlyAck to true. + * Note that this attribute is only meaningful on the cache that + * is initiating an operation; it does not matter what it is set to + * on the cache that receives the operation.
+ * {@link #setEarlyAck} {@link RegionAttributes#getEarlyAck}
+ + *
{@link SubscriptionAttributes} [default: {@link InterestPolicy#DEFAULT}]
+ *
How will the region in this cache subscribe to other distributed + * instances of this region. + *
+ * {@link #setSubscriptionAttributes} {@link RegionAttributes#getSubscriptionAttributes}
+ * + *
EnableAsyncConflation [default: false]
+ *
Whether or not conflation is enabled for sending + * messages to async peers. Async peers are those whose + * async-distribution-timeout gemfire.property is greater + * than zero. AsyncConflation is ignored if the scope is + * DISTRIBUTED_ACK or GLOBAL. + * Conflation is only done on entry update operations. It is done + * by dropping the earlier update from the message queue. + * {@link #setEnableAsyncConflation} {@link RegionAttributes#getEnableAsyncConflation}
+ *
poolName [default: null, meaning no pool]
+ *
Whether or not this region is a client that is to use + * connections from the named pool to communicate with servers. + * If null, then it is not a client. + * If non-null, then the named pool will be used. + * {@link #setPoolName} {@link RegionAttributes#getPoolName}
+ * + * + *
EnableSubscriptionConflation [default: false]
+ *
Whether or not conflation is enabled for sending + * messages from a cache server to its clients. Note: This parameter + * is only valid for cache server to client communication. It has no + * effect in peer to peer communication. + * If true, messages will be conflated before they are + * sent from a cache server to its clients. Only the latest value + * will be sent. + * Note that this attribute is only meaningful in a client server + * topology. + * {@link #setEnableSubscriptionConflation} {@link RegionAttributes#getEnableSubscriptionConflation}
+ *
Publisher [default: false]
+ *
Whether or not a region is a publisher. Publishers are regions + * that will have distributed write operations done on them. + * If a publisher is also a replicate then it will be used + * as the preferred source for initializing other replicates. + * {@link #setPublisher} {@link RegionAttributes#getPublisher}
+ *
isCloningEnabled [default: false]
+ *
Whether or not value is cloned before appling Deltas + * If false, value will not be cloned + * {@link #setCloningEnabled} {@link RegionAttributes#getCloningEnabled()}
+ *
+ *

Storage (see also package summary + * )

+ *
+ *
{@link DataPolicy} [default: DataPolicy.NORMAL]
+ *
Specifies the data storage policy.
+ * {@link #setDataPolicy} {@link RegionAttributes#getDataPolicy}
+ * + *
{@link MirrorType} [default: MirrorType.NONE]
+ *
Deprecated, use DataPolicy instead.
+ * + *
{@link #setEvictionAttributes(EvictionAttributes) EvictionAttributes}
+ *
{@link EvictionAttributes} are the replacement for the deprecated and removed CapacityController interface. + * EvictionAttributes describe the {@link EvictionAlgorithm} and the {@link EvictionAction} + * as well as the various conditions under which the algorithm perform the action + * e.g. when the maximum number of entries has been reached or + * the maximum percentage of JVM heap has been consumed. + * Setting EvictionAttributes installs an eviction controller + * on the Region instantiated with the associated RegionAttributes
+ * + *
KeyConstraint [default: null, meaning no constraint]
+ *
The Class to constrain the keys to in the region.
+ * {@link #setKeyConstraint} {@link RegionAttributes#getKeyConstraint}
+ * + *
ValueConstraint [default: null, meaning no constraint]
+ *
The Class to constrain the values to in the region. In addition to the + * utility of this for applications in general, a valueConstraint + * is helpful for compiling queries.
+ * {@link #setValueConstraint} {@link RegionAttributes#getValueConstraint}
+ * + *
InitialCapacity [default: 16]
+ *
The initial capacity of the map used for storing the entries.
+ * {@link java.util.HashMap} {@link #setInitialCapacity} + * {@link RegionAttributes#getInitialCapacity}
+ * + *
LoadFactor [default: 0.75]
+ *
The load factor of the map used for storing the entries.
+ * {@link java.util.HashMap} {@link #setLoadFactor} + * {@link RegionAttributes#getLoadFactor}
+ * + *
ConcurrencyLevel [default: 16]
+ *
The allowed concurrency among updates to values in the region is guided + * by the concurrencyLevel, which is used as a hint for internal + * sizing. The actual concurrency will vary. Ideally, you should choose a value + * to accommodate as many threads as will ever concurrently modify values in the + * region. Using a significantly higher value than you need can waste space and + * time, and a significantly lower value can lead to thread contention. But + * overestimates and underestimates within an order of magnitude do not usually + * have much noticeable impact. A value of one is appropriate when it is known + * that only one thread will modify and all others will only read.
+ * {@link #setConcurrencyLevel} {@link RegionAttributes#getConcurrencyLevel} + *
+ * + *
ConcurrencyChecksEnabled [default: false]
+ *
Enables a distributed versioning algorithm that detects concurrency + * conflicts in regions and ensures that changes to an + * entry are not applied in a different order in other members. This can + * cause operations to be conflated, so that some cache listeners may see + * an event while others do not, but it guarantees that the system will + * be consistent. + *
+ * + *
StatisticsEnabled [default: false]
+ *
Whether statistics are enabled for this region. The default is disabled, + * which conserves on memory.
+ * {@link #setStatisticsEnabled} {@link RegionAttributes#getStatisticsEnabled} + *
+ * + *
IgnoreJTA [default: false]
+ *
Whether JTA transactions are ignored for this region. The + * default is to look for and join JTA transactions for operations + * performed on a region. + * + *
DiskStoreName [default: null, meaning no disk store]
+ *
If not null then this region will write its data + * to the named {@link DiskStore}.
+ * {@link #setDiskStoreName} {@link RegionAttributes#getDiskStoreName}
+ * + *
DiskSynchronous [default: true]
+ *
If true then any writes to disk done for this region + * will be done synchronously. This means that they will be in the file system + * buffer before the operation doing the write returns.
+ * If false then any writes to disk done for this region + * will be done asynchronously. This means that they are queued up to be written + * and when they are actually written to the file system buffer is determined + * by the region's {@link DiskStore} configuration. + * Asynchronous writes will be conflated if the same entry is written while a + * previous operation for the same entry is still in the queue.
+ * {@link #setDiskSynchronous} {@link RegionAttributes#isDiskSynchronous}
+ + *
PersistBackup [default: false]
+ *
Whether or not a persistent backup should be made of the + * region.
+ * {@link #setPersistBackup} {@link RegionAttributes#getPersistBackup}
+ *
Deprecated, use {@link DataPolicy#PERSISTENT_REPLICATE} or {@link DataPolicy#PERSISTENT_PARTITION} instead.
+ * + *
DiskWriteAttributes [default: Asynchronously write to + * disk every second (a timeInterval of 1000 and a + * byteThreshold of 0). rollOplogs is set to true and + * maxOplogSize is set to 1024 MB]
+ *
How region data should be written to disk. Determines + * whether data should be written synchronously or asynchronously. + * Data that is written asynchronously can be written at a certain + * {@linkplain DiskWriteAttributes#getTimeInterval time interval} + * or once a certain number of {@linkplain + * DiskWriteAttributes#getBytesThreshold bytes of data} have been + * enqueued.
+ * {@link DiskWriteAttributes} {@link #setDiskWriteAttributes} {@link RegionAttributes#getDiskWriteAttributes}
+ *
Deprecated, use {@link #setDiskStoreName} and {@link #setDiskSynchronous} instead.
+ * + *
DiskDirs [default: Current working directory (user.dir {@linkplain System#getProperties system property})]
+ *
The directories to which the region's data are written. If + * multiple directories are used, GemFire will attempt to distribute the + * data evenly among them.
+ * {@link #setDiskDirs} {@link RegionAttributes#getDiskDirs}
+ *
Deprecated, use {@link #setDiskStoreName} instead.
+ * + *
DiskDirSizes [default: 10240 MB]
+ *
The size of the directory to which region's data is written.
+ * {@link #setDiskDirsAndSizes} {@link RegionAttributes#getDiskDirSizes}
+ *
Deprecated, use {@link #setDiskStoreName} instead.
+ * + * + *
{@link PartitionAttributes} [default: null, meaning no region partitioning]
+ *
How region data is partitioned among the members of the + * distributed system. + *
+ * {@link #setPartitionAttributes} {@link RegionAttributes#getPartitionAttributes}
+ * + *
{@link MembershipAttributes} [default: no required roles]
+ *
How access to the region is affected when one or more required roles + * are missing from the region membership. + *
+ * {@link #setMembershipAttributes} {@link RegionAttributes#getMembershipAttributes}
+ * + * + *
+ * + *

Locking

+ *
+ *
LockGrantor [default: false]
+ *
Should this process become lock grantor for the region?

+ * {@link #setLockGrantor} {@link RegionAttributes#isLockGrantor} + * {@link Region#becomeLockGrantor} + *
+ * + *

Querying

+ *
+ *
IndexMaintenanceSynchronous [default: false]
+ *
Are indexes built over in this region updated + * synchronously when the underlying data is + * modified?

+ * {@link #setIndexMaintenanceSynchronous} {@link + * RegionAttributes#getIndexMaintenanceSynchronous} + *
+ * + *

Note that the RegionAttributes are not distributed with the region. + * + *

Compatibility Rules

+ *

RegionAttributes Creation Constraints

+ * If any of the following compatibility rules are violated when + * {@link #create} is called then an + * {@link IllegalStateException} is thrown. + * See {@link #validateAttributes}. + * + *

Creation Constraints

+ *

Region Creation Constraints on RegionAttributes

+ * + * If any of the following rules are violated when {@link + * Region#createSubregion createSubregion} or {@link Cache#createRegion + * createRegion} are called, then an + * IllegalStateException is thrown. + * + *
    + *
  • A region with Scope.LOCAL can only have subregions with + * Scope.LOCAL.
  • + *
  • Scope.GLOBAL is illegal if there is any other cache in + * the distributed system that has the same region with + * Scope.DISTRIBUTED_NO_ACK or Scope.DISTRIBUTED_ACK. + *
  • + *
  • Scope.DISTRIBUTED_ACK is illegal if there is any other + * cache in the distributed system that has the same region with + * Scope.DISTRIBUTED_NO_ACK or Scope.GLOBAL. + *
  • + *
  • Scope.DISTRIBUTED_NO_ACK is illegal if there is any other + * cache in the distributed system that has the same region with + * Scope.DISTRIBUTED_ACK or Scope.GLOBAL.
  • + *
+ * + * @see RegionAttributes + * @see AttributesMutator + * @see Region#createSubregion(String, RegionAttributes) + * + * @author Eric Zoerner + * @since 3.0 + * @deprecated as of 6.5 use {@link Cache#createRegionFactory(RegionShortcut)} or {@link ClientCache#createClientRegionFactory(ClientRegionShortcut)} instead. + */ +@SuppressWarnings("synthetic-access") +public class AttributesFactory { + private final RegionAttributesImpl regionAttributes = new RegionAttributesImpl(); + + /** + * The default disk synchronous write setting + *

Current value: true each. + * @since 6.5 + */ + public static final boolean DEFAULT_DISK_SYNCHRONOUS = true; + + /** + * Creates a new instance of AttributesFactory ready to create a + * RegionAttributes with default settings. + */ + public AttributesFactory() { + } + + /** + * Creates a new instance of AttributesFactory ready to create a + * RegionAttributes with the same settings as those in the + * specified RegionAttributes. + * + * @param regionAttributes + * the RegionAttributes used to initialize this + * AttributesFactory + */ + @SuppressWarnings("deprecation") + public AttributesFactory(RegionAttributes regionAttributes) { + synchronized (this.regionAttributes) { + this.regionAttributes.cacheListeners = new ArrayList>(Arrays.asList(regionAttributes.getCacheListeners())); + } + this.regionAttributes.cacheLoader = regionAttributes.getCacheLoader(); + this.regionAttributes.cacheWriter = regionAttributes.getCacheWriter(); + this.regionAttributes.regionTimeToLive = regionAttributes + .getRegionTimeToLive().getTimeout(); + this.regionAttributes.regionTimeToLiveExpirationAction = regionAttributes + .getRegionTimeToLive().getAction(); + this.regionAttributes.regionIdleTimeout = regionAttributes + .getRegionIdleTimeout().getTimeout(); + this.regionAttributes.regionIdleTimeoutExpirationAction = regionAttributes + .getRegionIdleTimeout().getAction(); + + this.regionAttributes.entryTimeToLive = regionAttributes + .getEntryTimeToLive().getTimeout(); + this.regionAttributes.entryTimeToLiveExpirationAction = regionAttributes + .getEntryTimeToLive().getAction(); + this.regionAttributes.customEntryTimeToLive = regionAttributes + .getCustomEntryTimeToLive(); + this.regionAttributes.entryIdleTimeout = regionAttributes + .getEntryIdleTimeout().getTimeout(); + this.regionAttributes.entryIdleTimeoutExpirationAction = regionAttributes + .getEntryIdleTimeout().getAction(); + this.regionAttributes.customEntryIdleTimeout = regionAttributes + .getCustomEntryIdleTimeout(); + + this.regionAttributes.scope = regionAttributes.getScope(); + this.regionAttributes.dataPolicy = regionAttributes.getDataPolicy(); + this.regionAttributes.statisticsEnabled = regionAttributes.getStatisticsEnabled(); + this.regionAttributes.ignoreJTA = regionAttributes.getIgnoreJTA(); + this.regionAttributes.keyConstraint = regionAttributes.getKeyConstraint(); + this.regionAttributes.valueConstraint = regionAttributes + .getValueConstraint(); + this.regionAttributes.initialCapacity = regionAttributes + .getInitialCapacity(); + this.regionAttributes.loadFactor = regionAttributes.getLoadFactor(); + this.regionAttributes.concurrencyLevel = regionAttributes + .getConcurrencyLevel(); + this.regionAttributes.concurrencyChecksEnabled = regionAttributes.getConcurrencyChecksEnabled(); + this.regionAttributes.earlyAck = regionAttributes.getEarlyAck(); + this.regionAttributes.diskStoreName = regionAttributes.getDiskStoreName(); + if (this.regionAttributes.diskStoreName == null) { + this.regionAttributes.diskWriteAttributes = regionAttributes + .getDiskWriteAttributes(); + this.regionAttributes.diskDirs = regionAttributes.getDiskDirs(); + this.regionAttributes.diskSizes = regionAttributes.getDiskDirSizes(); + } + this.regionAttributes.diskSynchronous = regionAttributes.isDiskSynchronous(); + this.regionAttributes.indexMaintenanceSynchronous = regionAttributes + .getIndexMaintenanceSynchronous(); + this.regionAttributes.partitionAttributes = regionAttributes + .getPartitionAttributes(); + this.regionAttributes.evictionAttributes = (EvictionAttributesImpl)regionAttributes + .getEvictionAttributes(); + + this.regionAttributes.membershipAttributes = regionAttributes.getMembershipAttributes(); + this.regionAttributes.subscriptionAttributes = regionAttributes.getSubscriptionAttributes(); + this.regionAttributes.evictionAttributes = (EvictionAttributesImpl) regionAttributes.getEvictionAttributes(); + + this.regionAttributes.publisher = regionAttributes.getPublisher(); + this.regionAttributes.enableAsyncConflation = regionAttributes.getEnableAsyncConflation(); + this.regionAttributes.enableSubscriptionConflation = regionAttributes.getEnableSubscriptionConflation(); + this.regionAttributes.poolName = regionAttributes.getPoolName(); + this.regionAttributes.isCloningEnabled = regionAttributes.getCloningEnabled(); + this.regionAttributes.multicastEnabled = regionAttributes.getMulticastEnabled(); + this.regionAttributes.gatewaySenderIds = new CopyOnWriteArraySet(regionAttributes.getGatewaySenderIds()); + this.regionAttributes.asyncEventQueueIds = new CopyOnWriteArraySet(regionAttributes.getAsyncEventQueueIds()); + this.regionAttributes.isLockGrantor = regionAttributes.isLockGrantor(); // fix for bug 47067 + if (regionAttributes instanceof UserSpecifiedRegionAttributes) { + this.regionAttributes.setIndexes(((UserSpecifiedRegionAttributes) regionAttributes).getIndexes()); + } + + if (regionAttributes instanceof UserSpecifiedRegionAttributes) { + // Selectively set has* fields to true, propigating those non-default + // (aka user specified) fields as such + UserSpecifiedRegionAttributes nonDefault = (UserSpecifiedRegionAttributes) regionAttributes; + this.regionAttributes.initHasFields(nonDefault); + this.regionAttributes.requiresPoolName = nonDefault.requiresPoolName; + } else { + // Set all fields to false, essentially starting with a new set of defaults + this.regionAttributes.setAllHasFields(false); + + + +// +// // Special Partitioned Region handling by +// // pretending the user didn't explicitly ask for the default scope +// if (AbstractRegion.DEFAULT_SCOPE.equals(this.regionAttributes.getScope())) { +// this.regionAttributes.setHasScope(false); +// } + } + + this.regionAttributes.compressor = regionAttributes.getCompressor(); + } + + // CALLBACKS + + /** + * Sets the cache loader for the next RegionAttributes created. + * + * @param cacheLoader + * the cache loader or null if no loader + * @throws IllegalStateException if this region has a {@link #setPoolName pool name set} + */ + public void setCacheLoader(CacheLoader cacheLoader) + { + if (cacheLoader != null) { + if (AbstractRegion.isBridgeLoader(cacheLoader) && this.regionAttributes.getPoolName() != null) { + throw new IllegalStateException("A region with a pool name can not have a BridgeLoader or BridgeClient. Please use pools OR BridgeClient."); + } + } + this.regionAttributes.cacheLoader = cacheLoader; + this.regionAttributes.setHasCacheLoader(true); + } + + /** + * Sets the cache writer for the next RegionAttributes created. + * + * @param cacheWriter + * the cache writer or null if no cache writer + * @throws IllegalStateException if this region has a {@link #setPoolName pool name set} + */ + public void setCacheWriter(CacheWriter cacheWriter) + { + if (cacheWriter != null) { + if (AbstractRegion.isBridgeWriter(cacheWriter) && this.regionAttributes.getPoolName() != null) { + throw new IllegalStateException("A region with a pool name can not have a BridgeWriter or BridgeClient. Please use pools OR BridgeClient."); + } + } + this.regionAttributes.cacheWriter = cacheWriter; + this.regionAttributes.setHasCacheWriter(true); + } + + /** Sets the CacheListener for the next RegionAttributes created. + * Any existing cache listeners on this factory are removed. + * @param aListener a user defined CacheListener, null if no listener + * @deprecated as of GemFire 5.0, use {@link #addCacheListener} instead. + */ + @Deprecated + public void setCacheListener(CacheListener aListener) { + ArrayList> col; + if (aListener == null) { + col = null; + } else { + col = new ArrayList>(1); + col.add(aListener); + } + synchronized (this.regionAttributes) { + this.regionAttributes.cacheListeners = col; + } + this.regionAttributes.setHasCacheListeners(true); + } + /** + * Adds a cache listener to the end of the list of cache listeners on this factory. + * @param aListener the cache listener to add to the factory. + * @throws IllegalArgumentException if aListener is null + * @since 5.0 + */ + public void addCacheListener(CacheListener aListener) { + if (aListener == null) { + throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_ADDCACHELISTENER_PARAMETER_WAS_NULL.toLocalizedString()); + } + synchronized (this.regionAttributes) { + this.regionAttributes.addCacheListener(aListener); + } + } + /** + * Removes all cache listeners and then adds each listener in the specified array. + * @param newListeners a possibly null or empty array of listeners to add to this factory. + * @throws IllegalArgumentException if the newListeners array has a null element + * @since 5.0 + */ + public void initCacheListeners(CacheListener[] newListeners) { + synchronized (this.regionAttributes) { + if (newListeners == null || newListeners.length == 0) { + this.regionAttributes.cacheListeners = null; + } else { + List> nl = Arrays.asList(newListeners); + if (nl.contains(null)) { + throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_INITCACHELISTENERS_PARAMETER_HAD_A_NULL_ELEMENT.toLocalizedString()); + } + this.regionAttributes.cacheListeners = new ArrayList>(nl); + } + } + this.regionAttributes.setHasCacheListeners(true); + } + + + // EXPIRATION ATTRIBUTES + + /** + * Sets the idleTimeout expiration attributes for region entries for the next + * RegionAttributes created. + * Default is 0 which indicates no expiration of this type. + * + * @param idleTimeout + * the idleTimeout ExpirationAttributes for entries in this region + * @throws IllegalArgumentException + * if idleTimeout is null + */ + public void setEntryIdleTimeout(ExpirationAttributes idleTimeout) + { + if (idleTimeout == null) { + throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_IDLETIMEOUT_MUST_NOT_BE_NULL.toLocalizedString()); + } + this.regionAttributes.entryIdleTimeout = idleTimeout.getTimeout(); + this.regionAttributes.entryIdleTimeoutExpirationAction = idleTimeout + .getAction(); + this.regionAttributes.setHasEntryIdleTimeout(true); + } + + /** + * Sets the idleTimeout CustomExpiry for the next RegionAttributes + * created. + * + * @param custom the CustomExpiry to use; null means none will be used. + */ + public void setCustomEntryIdleTimeout(CustomExpiry custom) { + this.regionAttributes.customEntryIdleTimeout = custom; + this.regionAttributes.setHasCustomEntryIdleTimeout(true); + } + + /** + * Sets the timeToLive expiration attributes for region entries for the next + * RegionAttributes created. + * Default is 0 which indicates no expiration of this type. + * + * @param timeToLive + * the timeToLive ExpirationAttributes for entries in this region + * @throws IllegalArgumentException + * if timeToLive is null + */ + public void setEntryTimeToLive(ExpirationAttributes timeToLive) + { + if (timeToLive == null) { + throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_TIMETOLIVE_MUST_NOT_BE_NULL.toLocalizedString()); + } + this.regionAttributes.entryTimeToLive = timeToLive.getTimeout(); + this.regionAttributes.entryTimeToLiveExpirationAction = timeToLive + .getAction(); + this.regionAttributes.setHasEntryTimeToLive(true); + } + + /** + * Sets the custom timeToLive for the next RegionAttributes + * created. + * + * @param custom the CustomExpiry to use, none if the default for the region + * is to be used. + */ + public void setCustomEntryTimeToLive(CustomExpiry custom) { + this.regionAttributes.customEntryTimeToLive = custom; + this.regionAttributes.setHasCustomEntryTimeToLive(true); + } + + /** + * Sets the idleTimeout expiration attributes for the region itself for the + * next RegionAttributes created. + * Default is 0 which indicates no expiration of this type is set. + * + * @param idleTimeout + * the ExpirationAttributes for this region idleTimeout + * @throws IllegalArgumentException + * if idleTimeout is null + */ + public void setRegionIdleTimeout(ExpirationAttributes idleTimeout) + { + if (idleTimeout == null) { + throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_IDLETIMEOUT_MUST_NOT_BE_NULL.toLocalizedString()); + } + this.regionAttributes.regionIdleTimeout = idleTimeout.getTimeout(); + this.regionAttributes.regionIdleTimeoutExpirationAction = idleTimeout + .getAction(); + this.regionAttributes.setHasRegionIdleTimeout(true); + } + + + /** + * Sets the timeToLive expiration attributes for the region itself for the + * next RegionAttributes created. + * Default is 0 i.e. no expiration of this type. + * + * @param timeToLive + * the ExpirationAttributes for this region timeToLive + * @throws IllegalArgumentException + * if timeToLive is null + */ + public void setRegionTimeToLive(ExpirationAttributes timeToLive) + { + if (timeToLive == null) { + throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_TIMETOLIVE_MUST_NOT_BE_NULL.toLocalizedString()); + } + this.regionAttributes.regionTimeToLive = timeToLive.getTimeout(); + this.regionAttributes.regionTimeToLiveExpirationAction = timeToLive + .getAction(); + this.regionAttributes.setHasRegionTimeToLive(true); + } + + // DISTRIBUTION ATTRIBUTES + + /** + * Sets the scope for the next RegionAttributes created. + * Default scope is DISTRIBUTED_NO_ACK. Refer gemfire documentation for more details on this. + * @param scopeType + * the type of Scope to use for the region + * @throws IllegalArgumentException + * if scopeType is null + */ + public void setScope(Scope scopeType) + { + if (scopeType == null) { + throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_SCOPETYPE_MUST_NOT_BE_NULL.toLocalizedString()); + } + this.regionAttributes.setScope(scopeType); + } + + // STORAGE ATTRIBUTES + + /** + * Sets the EvictionController for the next RegionAttributes + * created. Use one of the creation methods on {@link EvictionAttributes} e.g. + * {@link EvictionAttributes#createLRUHeapAttributes()} to create the desired + * instance for this AttributesFactory + * + * @param evictAttrs + * Explains how and when eviction occurs in the Region. + */ + public void setEvictionAttributes(EvictionAttributes evictAttrs) { + if (evictAttrs != null) { + this.regionAttributes.evictionAttributes = (EvictionAttributesImpl) evictAttrs; + } else { + this.regionAttributes.evictionAttributes = new EvictionAttributesImpl(); + } + this.regionAttributes.setHasEvictionAttributes(true); + } + + /** Sets the mirror type for the next RegionAttributes created. + * @param mirrorType The type of mirroring to use for the region + * @throws IllegalArgumentException if mirrorType is null + * @deprecated use {@link #setDataPolicy} instead. + */ + @Deprecated + public void setMirrorType(MirrorType mirrorType) { + if (mirrorType == null) { + throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_MIRRORTYPE_MUST_NOT_BE_NULL.toLocalizedString()); + } + DataPolicy dp = mirrorType.getDataPolicy(); + if (dp.withReplication()) { + // requested a mirror type that has replication + // if current data policy is not replicated change it + if (!this.regionAttributes.getDataPolicy().withReplication()) { + setDataPolicy(dp); + } + } else { + // requested a mirror type none; + // if current data policy is replicated change it + if (this.regionAttributes.getDataPolicy().withReplication()) { + setDataPolicy(dp); + } + } + } + /** Sets the data policy for the next RegionAttributes created. + * Default data policy is 'Normal'. Please refer gemfire documentation for more details on this. + * @param dataPolicy The data policy to use for the region + * @throws IllegalArgumentException if dataPolicy is null + */ + public void setDataPolicy(DataPolicy dataPolicy) { + if (dataPolicy == null) { + throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_DATAPOLICY_MUST_NOT_BE_NULL.toLocalizedString()); + } + if (this.regionAttributes.partitionAttributes != null) { + if ( !PartitionedRegionHelper.ALLOWED_DATA_POLICIES.contains(dataPolicy) ) { + throw new IllegalStateException( LocalizedStrings.AttributesFactory_DATA_POLICIES_OTHER_THAN_0_ARE_NOT_SUPPORTED_FOR_PARTITIONED_REGIONS + .toLocalizedString(PartitionedRegionHelper.ALLOWED_DATA_POLICIES)); + } + } + this.regionAttributes.setDataPolicy(dataPolicy); + } + + + + /** Sets the key constraint for the next RegionAttributes created. + * Keys in the region will be constrained to this class (or subclass). + * Any attempt to store a key of an incompatible type in the region will + * cause a ClassCastException to be thrown. + * @param keyConstraint The Class to constrain the keys to, or null if no constraint + * @throws IllegalArgumentException if keyConstraint is a class + * denoting a primitive type + */ + public void setKeyConstraint(Class keyConstraint) { + if (keyConstraint != null && keyConstraint.isPrimitive()) + throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_KEYCONSTRAINT_MUST_NOT_BE_A_PRIMITIVE_TYPE.toLocalizedString()); + this.regionAttributes.keyConstraint = keyConstraint; + this.regionAttributes.setHasKeyConstraint(true); + } + + /** Sets the value constraint for the next RegionAttributes created. + * Values in the region will be constrained to this class (or subclass). + * Any attempt to store a value of an incompatible type in the region will + * cause a ClassCastException to be thrown. + * @param valueConstraint The Class to constrain the values to, or null if no constraint + * @throws IllegalArgumentException if valueConstraint is a class + * denoting a primitive type + */ + public void setValueConstraint(Class valueConstraint) { + if (valueConstraint != null && valueConstraint.isPrimitive()) + throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_VALUECONSTRAINT_MUST_NOT_BE_A_PRIMITIVE_TYPE.toLocalizedString()); + this.regionAttributes.valueConstraint = valueConstraint; + this.regionAttributes.setHasValueConstraint(true); + } + + + + // MAP ATTRIBUTES + /** Sets the entry initial capacity for the next RegionAttributes + * created. This value + * is used in initializing the map that holds the entries. + * Default is 16. + * @param initialCapacity the initial capacity of the entry map + * @throws IllegalArgumentException if initialCapacity is negative. + * @see java.util.HashMap + */ + public void setInitialCapacity(int initialCapacity) { + if (initialCapacity < 0) + throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_INITIALCAPACITY_MUST_BE_0.toLocalizedString()); + this.regionAttributes.initialCapacity = initialCapacity; + this.regionAttributes.setHasInitialCapacity(true); + } + + /** Sets the entry load factor for the next RegionAttributes + * created. This value is + * used in initializing the map that holds the entries. + * Default is 0.75. + * @param loadFactor the load factor of the entry map + * @throws IllegalArgumentException if loadFactor is nonpositive + * @see java.util.HashMap + */ + public void setLoadFactor(float loadFactor) { + if (loadFactor <= 0) + throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_LOADFACTOR_MUST_BE_0_VALUE_IS_0.toLocalizedString(new Float(loadFactor))); + this.regionAttributes.loadFactor = loadFactor; + this.regionAttributes.setHasLoadFactor(true); + } + + /** Sets the concurrency level of the next RegionAttributes + * created. This value is used in initializing the map that holds the entries. + * Default is 16. + * @param concurrencyLevel the concurrency level of the entry map + * @throws IllegalArgumentException if concurrencyLevel is nonpositive + */ + public void setConcurrencyLevel(int concurrencyLevel) { + if (concurrencyLevel <= 0) + throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_CONCURRENCYLEVEL_MUST_BE_0.toLocalizedString()); + this.regionAttributes.concurrencyLevel = concurrencyLevel; + this.regionAttributes.setHasConcurrencyLevel(true); + } + + /** + * Enables or disabled concurrent modification checks. Concurrency checks are enabled + * by default. + * @since 7.0 + * @param concurrencyChecksEnabled whether to perform concurrency checks on operations + */ + public void setConcurrencyChecksEnabled(boolean concurrencyChecksEnabled) { + this.regionAttributes.concurrencyChecksEnabled = concurrencyChecksEnabled; + this.regionAttributes.setHasConcurrencyChecksEnabled(true); + } + + /** + * Sets whether or not a persistent backup should be made of the + * region. + * + * @since 3.2 + * @deprecated as of GemFire 5.0, use {@link DataPolicy#PERSISTENT_REPLICATE} instead + */ + @Deprecated + public void setPersistBackup(boolean persistBackup) { + if (persistBackup) { + if (!this.regionAttributes.getDataPolicy().withPersistence()) { + if (this.regionAttributes.getDataPolicy().withPartitioning()) { + setDataPolicy(DataPolicy.PERSISTENT_PARTITION); + } else { + setDataPolicy(DataPolicy.PERSISTENT_REPLICATE); + } + } + } else { + // It is less clear what we should do here for backwards compat. + // If the current data policy is persist then we need to change it + // otherwise just leave it alone + if (this.regionAttributes.getDataPolicy().withReplication()) { + setDataPolicy(DataPolicy.REPLICATE); + } else if (this.regionAttributes.getDataPolicy().withPartitioning()) { + setDataPolicy(DataPolicy.PARTITION); + } + } + } + /** + * Sets whether or not acks are sent after an operation is processed. + * + * @since 4.1 + * @deprecated This setting no longer has any effect. + */ + @Deprecated + public void setEarlyAck(boolean earlyAck) { + this.regionAttributes.earlyAck = earlyAck; + this.regionAttributes.setHasEarlyAck(true); + } + + /** + * Sets whether or not this region should be considered a publisher. + * + * @since 4.2.3 + * @deprecated as of 6.5 + */ + @Deprecated + public void setPublisher(boolean v) { +// this.regionAttributes.publisher = v; +// this.regionAttributes.setHasPublisher(true); + } + + /** + * Sets whether or not conflation is enabled for sending messages + * to async peers. + * Default value is false. + * + * @since 4.2.3 + */ + public void setEnableAsyncConflation(boolean enableAsyncConflation) { + this.regionAttributes.enableAsyncConflation = enableAsyncConflation; + this.regionAttributes.setHasEnableAsyncConflation(true); + } + + + /** + * Sets whether or not conflation is enabled for sending messages + * from a cache server to its clients. + * Default is false. + * + * @since 5.0 + */ + public void setEnableSubscriptionConflation(boolean enableSubscriptionConflation) { + this.regionAttributes.enableSubscriptionConflation = enableSubscriptionConflation; + this.regionAttributes.setHasEnableSubscriptionConflation(true); + } + + /** + * adds a gateway sender to the end of list of gateway senders on this factory + * @param gatewaySenderId + * @throws IllegalArgumentException if gatewaySender is null + * @since 7.0 + */ + public void addGatewaySenderId(String gatewaySenderId) { + if (gatewaySenderId == null) { + throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_GATEWAY_SENDER_ID_IS_NULL.toLocalizedString()); + } + synchronized (this.regionAttributes) { + this.regionAttributes.addGatewaySenderId(gatewaySenderId); + } + } + + /** + * Adds a AsyncEventQueue to the end of list of async event queues on this factory + * @param asyncEventQueueId + * @throws IllegalArgumentException if gatewaySender is null + * @since 7.0 + */ + public void addAsyncEventQueueId(String asyncEventQueueId) { + if (asyncEventQueueId == null) { + throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_GATEWAY_SENDER_ID_IS_NULL.toLocalizedString()); + } + synchronized (this.regionAttributes) { + this.regionAttributes.addAsyncEventQueueId(asyncEventQueueId); + } + } + + /** + * Sets whether or not conflation is enabled for sending messages + * from a cache server to its clients. + * + * @since 5.0 + * @deprecated as of 5.7 use {@link #setEnableSubscriptionConflation} instead. + */ + @Deprecated + public void setEnableBridgeConflation(boolean enableBridgeConflation) { + setEnableSubscriptionConflation(enableBridgeConflation); + } + + /** + * Sets whether or not conflation is enabled for sending messages + * from a cache server to its clients. + * + * @deprecated as of GemFire 5.0, use {@link #setEnableSubscriptionConflation} + */ + @Deprecated + public void setEnableConflation(boolean enableBridgeConflation) { + setEnableSubscriptionConflation(enableBridgeConflation); + } + + /** + * Returns whether or not disk writes are asynchronous. + * + * @see Region#writeToDisk + * + * @since 3.2 + * @deprecated as of 6.5 use {@link #setDiskStoreName} instead + */ + @Deprecated + public void setDiskWriteAttributes(DiskWriteAttributes attrs) { + if (this.regionAttributes.getDiskStoreName() != null) { + throw new IllegalStateException(LocalizedStrings.DiskStore_Deprecated_API_0_Cannot_Mix_With_DiskStore_1 + .toLocalizedString(new Object[] {"setDiskWriteAttributes", this.regionAttributes.getDiskStoreName()})); + } + this.regionAttributes.diskWriteAttributes = attrs; + this.regionAttributes.setHasDiskWriteAttributes(true); + if (attrs != null) { + // keep new apis in sync with old + this.regionAttributes.diskSynchronous = attrs.isSynchronous(); + } + } + + /** + * Sets the directories with + * the default size of 10240 MB to which the region's data is written + * + * @throws IllegalArgumentException if a directory does not exist + * + * @since 3.2 + * @deprecated as of 6.5 use {@link DiskStoreFactory#setDiskDirs} instead + */ + @Deprecated + public void setDiskDirs(File[] diskDirs) { + if (this.regionAttributes.getDiskStoreName() != null) { + throw new IllegalStateException(LocalizedStrings.DiskStore_Deprecated_API_0_Cannot_Mix_With_DiskStore_1 + .toLocalizedString(new Object[] {"setDiskDirs", this.regionAttributes.getDiskStoreName()})); + } + DiskStoreFactoryImpl.checkIfDirectoriesExist(diskDirs); + this.regionAttributes.diskDirs = diskDirs; + this.regionAttributes.diskSizes = new int[diskDirs.length]; + for (int i=0; i < diskDirs.length; i++) { + this.regionAttributes.diskSizes[i] = DiskStoreFactory.DEFAULT_DISK_DIR_SIZE; + } + if (!this.regionAttributes.hasDiskWriteAttributes() + && !this.regionAttributes.hasDiskSynchronous()) { + // switch to the old default + this.regionAttributes.diskSynchronous = false; + this.regionAttributes.diskWriteAttributes = DiskWriteAttributesImpl.getDefaultAsyncInstance(); + } + this.regionAttributes.setHasDiskDirs(true); + } + + /** + * Sets the DiskStore name attribute. + * This causes the region to use the {@link DiskStore}. + * @param name the name of the diskstore + * @since 6.5 + */ + public void setDiskStoreName(String name) { + if (this.regionAttributes.hasDiskDirs() || this.regionAttributes.hasDiskWriteAttributes()) { + throw new IllegalStateException(LocalizedStrings.DiskStore_Deprecated_API_0_Cannot_Mix_With_DiskStore_1 + .toLocalizedString(new Object[] {"setDiskDirs or setDiskWriteAttributes", name})); + } + this.regionAttributes.diskStoreName = name; + this.regionAttributes.setHasDiskStoreName(true); + } + + /** + * Sets whether or not the writing to the disk is synchronous. + * Default is true. + * + * @param isSynchronous + * boolean if true indicates synchronous writes + * @since 6.5 + */ + @SuppressWarnings("deprecation") + public void setDiskSynchronous(boolean isSynchronous) + { + this.regionAttributes.diskSynchronous = isSynchronous; + this.regionAttributes.setHasDiskSynchronous(true); + if (this.regionAttributes.hasDiskWriteAttributes()) { + DiskWriteAttributesFactory dwaf = new DiskWriteAttributesFactory(this.regionAttributes.diskWriteAttributes); + dwaf.setSynchronous(isSynchronous); + this.regionAttributes.diskWriteAttributes = dwaf.create(); + } else { + if (isSynchronous) { + this.regionAttributes.diskWriteAttributes = DiskWriteAttributesImpl.getDefaultSyncInstance(); + } else { + this.regionAttributes.diskWriteAttributes = DiskWriteAttributesImpl.getDefaultAsyncInstance(); + } + } + } + + /** + * Sets the directories to which the region's data is written and also set their sizes in megabytes + * + * @throws IllegalArgumentException if a dir does not exist or the length of the size array + * does not match to the length of the dir array or the given length is not a valid positive number + * + * @since 5.1 + * @deprecated as of 6.5 use {@link DiskStoreFactory#setDiskDirsAndSizes} instead + */ + @Deprecated + public void setDiskDirsAndSizes(File[] diskDirs,int[] diskSizes) { + if (this.regionAttributes.getDiskStoreName() != null) { + throw new IllegalStateException(LocalizedStrings.DiskStore_Deprecated_API_0_Cannot_Mix_With_DiskStore_1 + .toLocalizedString(new Object[] {"setDiskDirsAndSizes", this.regionAttributes.getDiskStoreName()})); + } + DiskStoreFactoryImpl.checkIfDirectoriesExist(diskDirs); + this.regionAttributes.diskDirs = diskDirs; + if(diskSizes.length != this.regionAttributes.diskDirs.length) { + throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_NUMBER_OF_DISKSIZES_IS_0_WHICH_IS_NOT_EQUAL_TO_NUMBER_OF_DISK_DIRS_WHICH_IS_1.toLocalizedString(new Object[] {Integer.valueOf(diskSizes.length), Integer.valueOf(diskDirs.length)})); + } + DiskStoreFactoryImpl.verifyNonNegativeDirSize(diskSizes); + this.regionAttributes.diskSizes = diskSizes; + if (!this.regionAttributes.hasDiskWriteAttributes() + && !this.regionAttributes.hasDiskSynchronous()) { + // switch to the old default + this.regionAttributes.diskSynchronous = false; + this.regionAttributes.diskWriteAttributes = DiskWriteAttributesImpl.getDefaultAsyncInstance(); + } + this.regionAttributes.setHasDiskDirs(true); + } + + /** + * Sets the PartitionAttributes that describe how the + * region is partitioned among members of the distributed system. This + * also establishes a data policy of {@link DataPolicy#PARTITION PARTITION}, + * if the data policy has not already been set. + * + * @since 5.0 + */ + public void setPartitionAttributes(PartitionAttributes partition) { + if (partition != null) { + if (! this.regionAttributes.hasDataPolicy()) { + this.regionAttributes.dataPolicy = PartitionedRegionHelper.DEFAULT_DATA_POLICY; + } + else if ( !PartitionedRegionHelper.ALLOWED_DATA_POLICIES.contains(this.regionAttributes.dataPolicy) ) { + throw new IllegalStateException(LocalizedStrings.AttributesFactory_DATA_POLICY_0_IS_NOT_ALLOWED_FOR_A_PARTITIONED_REGION_DATAPOLICIES_OTHER_THAN_1_ARE_NOT_ALLOWED + .toLocalizedString(new Object[] {this.regionAttributes.dataPolicy, PartitionedRegionHelper.ALLOWED_DATA_POLICIES})); + } + if (this.regionAttributes.hasPartitionAttributes() + && this.regionAttributes.partitionAttributes instanceof PartitionAttributesImpl + && partition instanceof PartitionAttributesImpl) { + // Make a copy and call merge on it to prevent bug 51616 + PartitionAttributesImpl copy = ((PartitionAttributesImpl) this.regionAttributes.partitionAttributes).copy(); + copy.merge((PartitionAttributesImpl) partition); + this.regionAttributes.partitionAttributes = copy; + } else { + this.regionAttributes.partitionAttributes = partition; + this.regionAttributes.setHasPartitionAttributes(true); + } + } + else { + this.regionAttributes.partitionAttributes = null; + this.regionAttributes.setHasPartitionAttributes(false); + } + } + + protected void setBucketRegion(boolean b) { + this.regionAttributes.isBucketRegion = b; + } + + /** + * Sets the MembershipAttributes that describe the membership + * roles required for reliable access to the region. + * + * @since 5.0 + */ + public void setMembershipAttributes(MembershipAttributes membership) { + this.regionAttributes.membershipAttributes = membership; + this.regionAttributes.setHasMembershipAttributes(true); + } + + /** + * Sets the SubscriptionAttributes that describe how the region + * will subscribe to other distributed cache instances of the region. + * + * @since 5.0 + */ + public void setSubscriptionAttributes(SubscriptionAttributes subscription) { + this.regionAttributes.subscriptionAttributes = subscription; + this.regionAttributes.setHasSubscriptionAttributes(true); + } + + /** + * Set how indexes on the region should be maintained. It will be either synchronous + * or asynchronous. + * Default is true. + */ + public void setIndexMaintenanceSynchronous(boolean synchronous) { + this.regionAttributes.indexMaintenanceSynchronous = synchronous; + this.regionAttributes.setHasIndexMaintenanceSynchronous(true); + } + + // STATISTICS + /** Sets whether statistics are enabled for this region and its entries. + * Default is false. + * @param statisticsEnabled whether statistics are enabled + */ + public void setStatisticsEnabled(boolean statisticsEnabled) { + this.regionAttributes.statisticsEnabled = statisticsEnabled; + this.regionAttributes.setHasStatisticsEnabled(true); + } + + /** + * Sets the flag telling a region to ignore JTA transactions. + * Default is false. + * @since 5.0 + */ + public void setIgnoreJTA(boolean flag) { + this.regionAttributes.ignoreJTA = flag; + this.regionAttributes.setHasIgnoreJTA(true); + } + + /** Sets whether this region should become lock grantor. + * Default value is false. + * @param isLockGrantor whether this region should become lock grantor + */ + public void setLockGrantor(boolean isLockGrantor) { + this.regionAttributes.isLockGrantor = isLockGrantor; + this.regionAttributes.setHasIsLockGrantor(true); + } + + /** Sets whether distributed operations on this region should attempt + to use multicast. Multicast must also be enabled in the + cache's DistributedSystem (see + "mcast-port"). + Default is false. + @since 5.0 + @see RegionAttributes#getMulticastEnabled + */ + public void setMulticastEnabled(boolean value) { + this.regionAttributes.multicastEnabled = value; + this.regionAttributes.setHasMulticastEnabled(true); + } + /** + * Sets cloning on region. + * Default is false. + * + * @param cloningEnable + * @since 6.1 + * @see RegionAttributes#getCloningEnabled() + */ + public void setCloningEnabled(boolean cloningEnable) { + this.regionAttributes.isCloningEnabled = cloningEnable; + this.regionAttributes.setHasCloningEnabled(true); + } + + + /** + * Sets the pool name attribute. + * This causes regions that use these attributes + * to be a client region which communicates with the + * servers that the connection pool communicates with. + *

If this attribute is set to null or "" + * then the connection pool is disabled causing regions that use these attributes + * to be communicate with peers instead of servers. + *

The named connection pool must exist on the cache at the time these + * attributes are used to create a region. See {@link PoolManager#createFactory} + * for how to create a connection pool. + * @param name the name of the connection pool to use; if null + * or "" then the connection pool is disabled for regions + * using these attributes. + * @throws IllegalStateException if a cache loader or cache writer has already + * been set. + * @since 5.7 + */ + public void setPoolName(String name) { + String nm = name; + if ("".equals(nm)) { + nm = null; + } + if (nm != null) { + // make sure a cache listener or writer has not already been installed + if (this.regionAttributes.getCacheLoader() != null + && AbstractRegion.isBridgeLoader(this.regionAttributes.getCacheLoader())) { + throw new IllegalStateException("A region with a bridge loader can not have a pool name."); + } + if (this.regionAttributes.getCacheWriter() != null + && AbstractRegion.isBridgeWriter(this.regionAttributes.getCacheWriter())) { + throw new IllegalStateException("A region with a bridge writer can not have a pool name."); + } + } + this.regionAttributes.poolName = nm; + this.regionAttributes.setHasPoolName(true); + + } + + /** + * Sets this region's compressor for compressing entry values. + * @since 8.0 + * @param compressor a compressor. + */ + public void setCompressor(Compressor compressor) { + this.regionAttributes.compressor = compressor; + this.regionAttributes.setHasCompressor(true); + + // Cloning must be enabled when a compressor is set + if (compressor != null) { + setCloningEnabled(true); + } + } + + // FACTORY METHOD + + /** Creates a RegionAttributes with the current settings. + * @return the newly created RegionAttributes + * @throws IllegalStateException if the current settings violate the + * compatibility rules + * @deprecated as of GemFire 5.0, use {@link #create} instead + */ + @Deprecated + public RegionAttributes createRegionAttributes() { + return create(); + } + /** Creates a RegionAttributes with the current settings. + * @return the newly created RegionAttributes + * @throws IllegalStateException if the current settings violate the + * compatibility rules + * @since 5.0 + */ + @SuppressWarnings("unchecked") + public RegionAttributes create() { + if (this.regionAttributes.hasDataPolicy() && + this.regionAttributes.dataPolicy.withPartitioning() && + this.regionAttributes.partitionAttributes == null) { + this.regionAttributes.partitionAttributes = (new PartitionAttributesFactory()).create(); + } + // As of 6.5 we automatically enable stats if expiration is used. + { + RegionAttributesImpl attrs = this.regionAttributes; + if (!attrs.hasStatisticsEnabled() && !attrs.getStatisticsEnabled() && + (attrs.getRegionTimeToLive().getTimeout() != 0 || + attrs.getRegionIdleTimeout().getTimeout() != 0 || + attrs.getEntryTimeToLive().getTimeout() != 0 || + attrs.getEntryIdleTimeout().getTimeout() != 0 || + attrs.getCustomEntryIdleTimeout() != null || + attrs.getCustomEntryTimeToLive() != null) + ) { + // @todo we could do some more implementation work so that we would + // not need to enable stats unless entryIdleTimeout is enabled. + // We need the stats in that case because we need a new type of RegionEntry + // so we know that last time it was accessed. But for all the others we + // the stat less region keeps track of everything we need. + // The only problem is that some places in the code are conditionalized + // on statisticsEnabled. + setStatisticsEnabled(true); + } + // SQLFabric does not handle PRELOADED, so do not change the policy + if (attrs.getDataPolicy().withReplication() + && !attrs.getDataPolicy().withPersistence() + && attrs.getScope().isDistributed() + && !GemFireCacheImpl.sqlfSystem()) { + RegionAttributesImpl rattr = attrs; + if (!rattr.isForBucketRegion()) { + if (attrs.getEvictionAttributes().getAction().isLocalDestroy() + || attrs.getEntryIdleTimeout().getAction().isLocal() + || attrs.getEntryTimeToLive().getAction().isLocal() + || attrs.getRegionIdleTimeout().getAction().isLocalInvalidate() + || attrs.getRegionTimeToLive().getAction().isLocalInvalidate()) { + // new to 6.5; switch to PRELOADED and interest ALL + setDataPolicy(DataPolicy.PRELOADED); + setSubscriptionAttributes(new SubscriptionAttributes(InterestPolicy.ALL)); + } + } + } + } + validateAttributes(this.regionAttributes); + return (RegionAttributes)this.regionAttributes.clone(); + } + + /** + * Validates that the attributes are consistent with each other. + * The following rules are checked and enforced: +

    +
  • If the data policy {@link DataPolicy#withReplication uses replication} + and the scope is {@link Scope#isDistributed distributed} then the + following are incompatible: +
      +
    • ExpirationAction.LOCAL_INVALIDATE on the region
    • ExpirationAction.LOCAL_DESTROY on the entries +
    • ExpirationAction.LOCAL_INVALIDATE on the entries
    • +
    • An LRU with local destroy eviction action
    • +
    +
  • +
  • Region or entry expiration + is incompatible with disabled statistics on the region
  • +
  • Entry expiration + is incompatible with the {@link DataPolicy#EMPTY} data policy
  • +
  • {@link EvictionAttributes Eviction} + is incompatible with the {@link DataPolicy#EMPTY} data policy
  • +
+ * @param attrs the attributes to validate + * @throws IllegalStateException if the attributes are not consistent with each other. + * @since 3.5 + */ + public static void validateAttributes(RegionAttributes attrs) { + // enforce the creation constraints + + if (attrs.getDataPolicy().withReplication() + && attrs.getScope().isDistributed()) { + boolean isForBucketRegion = false; + if (attrs instanceof RegionAttributesImpl) { + RegionAttributesImpl regionAttributes = (RegionAttributesImpl)attrs; + if (regionAttributes.isForBucketRegion()) { + isForBucketRegion = true; + } + } + if (!isForBucketRegion) { + ExpirationAction idleAction = attrs.getEntryIdleTimeout().getAction(); + ExpirationAction ttlAction = attrs.getEntryTimeToLive().getAction(); + + if (idleAction == ExpirationAction.LOCAL_DESTROY + || ttlAction == ExpirationAction.LOCAL_DESTROY) { + throw new IllegalStateException(LocalizedStrings.AttributesFactory_EXPIRATIONACTIONLOCAL_DESTROY_ON_THE_ENTRIES_IS_INCOMPATIBLE_WITH_DISTRIBUTED_REPLICATION.toLocalizedString()); + } + + if (attrs.getEvictionAttributes().getAction().isLocalDestroy()) { + throw new IllegalStateException(LocalizedStrings.AttributesFactory_AN_EVICTION_CONTROLLER_WITH_LOCAL_DESTROY_EVICTION_ACTION_IS_INCOMPATIBLE_WITH_DISTRIBUTED_REPLICATION.toLocalizedString()); + } + + if (attrs.getRegionIdleTimeout().getAction() == ExpirationAction.LOCAL_INVALIDATE + || attrs.getRegionTimeToLive().getAction() == ExpirationAction.LOCAL_INVALIDATE) { + throw new IllegalStateException(LocalizedStrings.AttributesFactory_EXPIRATIONACTIONLOCAL_INVALIDATE_ON_THE_REGION_IS_INCOMPATIBLE_WITH_DISTRIBUTED_REPLICATION.toLocalizedString()); + } + + if (idleAction == ExpirationAction.LOCAL_INVALIDATE + || ttlAction == ExpirationAction.LOCAL_INVALIDATE) { + throw new IllegalStateException(LocalizedStrings.AttributesFactory_EXPIRATIONACTIONLOCAL_INVALIDATE_ON_THE_ENTRIES_IS_INCOMPATIBLE_WITH_DISTRIBUTED_REPLICATION.toLocalizedString()); + } + //TODO: Is it possible to add this check while region is getting created +// for(String senderId : attrs.getGatewaySenderIds()){ +// if(sender.isParallel()){ +// throw new IllegalStateException( +// LocalizedStrings.AttributesFactory_PARALLELGATEWAYSENDER_0_IS_INCOMPATIBLE_WITH_DISTRIBUTED_REPLICATION +// .toLocalizedString(sender)); +// } +// } + } + } + + if (attrs.getDiskStoreName() != null) { + EvictionAttributes ea = attrs.getEvictionAttributes(); + if (!attrs.getDataPolicy().withPersistence() && (ea != null && ea.getAction() != EvictionAction.OVERFLOW_TO_DISK)) { + throw new IllegalStateException(LocalizedStrings.DiskStore_IS_USED_IN_NONPERSISTENT_REGION.toLocalizedString()); + } + } + + if (!attrs.getStatisticsEnabled() && + (attrs.getRegionTimeToLive().getTimeout() != 0 || + attrs.getRegionIdleTimeout().getTimeout() != 0 || + attrs.getEntryTimeToLive().getTimeout() != 0 || + attrs.getEntryIdleTimeout().getTimeout() != 0 || + attrs.getCustomEntryIdleTimeout() != null || + attrs.getCustomEntryTimeToLive() != null) + ) { + throw new IllegalStateException(LocalizedStrings.AttributesFactory_STATISTICS_MUST_BE_ENABLED_FOR_EXPIRATION.toLocalizedString()); + } + + if (attrs.getDataPolicy() == DataPolicy.EMPTY) { + if (attrs.getEntryTimeToLive().getTimeout() != 0 || + attrs.getEntryIdleTimeout().getTimeout() != 0 || + attrs.getCustomEntryTimeToLive() != null || + attrs.getCustomEntryIdleTimeout() != null + ) { + throw new IllegalStateException(LocalizedStrings.AttributesFactory_IF_THE_DATA_POLICY_IS_0_THEN_ENTRY_EXPIRATION_IS_NOT_ALLOWED + .toLocalizedString(attrs.getDataPolicy())); + } + if (!attrs.getEvictionAttributes().getAlgorithm().isNone()) { + throw new IllegalStateException(LocalizedStrings.AttributesFactory_IF_THE_DATA_POLICY_IS_0_THEN_EVICTION_IS_NOT_ALLOWED + .toLocalizedString(attrs.getDataPolicy())); + } + } + if (attrs.getMembershipAttributes().hasRequiredRoles()) { + if (attrs.getScope().isLocal()) { + throw new IllegalStateException(LocalizedStrings.AttributesFactory_IF_THE_MEMBERSHIP_ATTRIBUTES_HAS_REQUIRED_ROLES_THEN_SCOPE_MUST_NOT_BE_LOCAL.toLocalizedString()); + } + } + if (attrs.getPoolName() != null) { + if (attrs.getCacheLoader() != null && AbstractRegion.isBridgeLoader(attrs.getCacheLoader())) { + throw new IllegalStateException("A region with a pool name can not have a BridgeLoader or BridgeClient. Please use pools OR BridgeClient."); + } + if (attrs.getCacheWriter() != null && AbstractRegion.isBridgeWriter(attrs.getCacheWriter())) { + throw new IllegalStateException("A region with a pool name can not have a BridgeWriter or BridgeClient. Please use pools OR BridgeClient."); + } + } + + final PartitionAttributes pa = attrs.getPartitionAttributes(); + // Validations for PartitionRegion Attributes + if (pa != null) { + ((PartitionAttributesImpl)pa).validateWhenAllAttributesAreSet(attrs instanceof RegionAttributesCreation); + ExpirationAttributes regionIdleTimeout = attrs.getRegionIdleTimeout(); + ExpirationAttributes regionTimeToLive = attrs.getRegionTimeToLive(); + if ((regionIdleTimeout.getAction().isInvalidate() && regionIdleTimeout.getTimeout() > 0) + || (regionIdleTimeout.getAction().isLocalInvalidate() && regionIdleTimeout.getTimeout() > 0) + || (regionTimeToLive.getAction().isInvalidate() && regionTimeToLive.getTimeout() > 0) + || (regionTimeToLive.getAction().isLocalInvalidate()) && regionTimeToLive.getTimeout() > 0 ) { + throw new IllegalStateException( + LocalizedStrings.AttributesFactory_INVALIDATE_REGION_NOT_SUPPORTED_FOR_PR.toLocalizedString()); + } + + if ((regionIdleTimeout.getAction().isDestroy() && regionIdleTimeout.getTimeout() > 0) + || (regionIdleTimeout.getAction().isLocalDestroy() && regionIdleTimeout.getTimeout() > 0) + || (regionTimeToLive.getAction().isDestroy() && regionTimeToLive.getTimeout() > 0) + || (regionTimeToLive.getAction().isLocalDestroy() && regionTimeToLive.getTimeout() > 0)) { + throw new IllegalStateException( + LocalizedStrings.AttributesFactory_DESTROY_REGION_NOT_SUPPORTED_FOR_PR + .toLocalizedString()); + } + + ExpirationAttributes entryIdleTimeout = attrs.getEntryIdleTimeout(); + ExpirationAttributes entryTimeToLive = attrs.getEntryTimeToLive(); + if ((entryIdleTimeout.getAction().isLocalDestroy() && entryIdleTimeout.getTimeout() > 0) + || (entryTimeToLive.getAction().isLocalDestroy() && entryTimeToLive.getTimeout() > 0)) { + throw new IllegalStateException( + LocalizedStrings.AttributesFactory_LOCAL_DESTROY_IS_NOT_SUPPORTED_FOR_PR.toLocalizedString()); + } + if ((entryIdleTimeout.getAction().isLocalInvalidate() && entryIdleTimeout.getTimeout() > 0) + || (entryTimeToLive.getAction().isLocalInvalidate() && entryTimeToLive.getTimeout() > 0)) { + throw new IllegalStateException( + LocalizedStrings.AttributesFactory_LOCAL_INVALIDATE_IS_NOT_SUPPORTED_FOR_PR.toLocalizedString()); + } + + if (attrs instanceof UserSpecifiedRegionAttributes) { + UserSpecifiedRegionAttributes rac = (UserSpecifiedRegionAttributes) attrs; + if (rac.hasScope()) { + throw new IllegalStateException(LocalizedStrings.AttributesFactory_SETTING_SCOPE_ON_A_PARTITIONED_REGIONS_IS_NOT_ALLOWED.toLocalizedString()); + } + } + + if (attrs.getPoolName() != null) { + throw new IllegalStateException("Setting pool name on a Partitioned Region is not allowed"); + } + +// if (attrs.getScope() == Scope.GLOBAL) { +// throw new IllegalStateException( +// "Global Scope is incompatible with Partitioned Regions"); +// } +// if (attrs.getScope() == Scope.LOCAL) { +// throw new IllegalStateException( +// "Local Scope is incompatible with Partitioned Regions"); +// } + if (pa.getTotalMaxMemory() <= 0) { + throw new IllegalStateException(LocalizedStrings.AttributesFactory_TOTAL_SIZE_OF_PARTITION_REGION_MUST_BE_0.toLocalizedString()); + } +// listeners are supported here as of v5.1 +// if (attrs.getCacheListeners().length > 0) { +// throw new IllegalStateException( +// "Can not add cache listeners to RegionAttributes when PartitionAttributes are set."); +// } +// loaders are supported here as of v5.1 +// if (attrs.getCacheLoader() != null) { +// throw new IllegalStateException( +// "Can not set CacheLoader in RegionAttributes when PartitionAttributes are set."); +// } + if ( ! PartitionedRegionHelper.ALLOWED_DATA_POLICIES.contains(attrs.getDataPolicy())) { + throw new IllegalStateException(LocalizedStrings.AttributesFactory_DATA_POLICIES_OTHER_THAN_0_ARE_NOT_ALLOWED_IN_PARTITIONED_REGIONS + .toLocalizedString(PartitionedRegionHelper.ALLOWED_DATA_POLICIES)); + } +// if ( attrs.getDataPolicy().isEmpty() && pa.getLocalMaxMemory() != 0) { +// throw new IllegalStateException( +// "A non-zero PartitionAttributes localMaxMemory setting is not compatible" + +// " with an empty DataPolicy. Please use DataPolicy.NORMAL instead."); +// } + if (pa.getLocalMaxMemory() < 0) { + throw new IllegalStateException(LocalizedStrings.AttributesFactory_PARTITIONATTRIBUTES_LOCALMAXMEMORY_MUST_NOT_BE_NEGATIVE.toLocalizedString()); + } + if (attrs.isLockGrantor() == true) { + throw new IllegalStateException(LocalizedStrings.AttributesFactory_SETLOCKGRANTERTRUE_IS_NOT_ALLOWED_IN_PARTITIONED_REGIONS.toLocalizedString()); + } + if (pa.getLocalMaxMemory() == 0 && attrs.getDataPolicy() == DataPolicy.PERSISTENT_PARTITION) { + throw new IllegalStateException("Persistence is not allowed when local-max-memory is zero."); + } + } + + if (null != attrs.getCompressor() && !attrs.getCloningEnabled()) { + throw new IllegalStateException("Cloning cannot be disabled when a compressor is set."); + } + } + + + private static class RegionAttributesImpl + extends UserSpecifiedRegionAttributes implements Cloneable, Serializable { + public Set gatewaySenderIds; + public Set asyncEventQueueIds; + private static final long serialVersionUID = -3663000883567530374L; + + ArrayList> cacheListeners; + CacheLoader cacheLoader; + CacheWriter cacheWriter; + int regionTimeToLive = 0; + ExpirationAction regionTimeToLiveExpirationAction = ExpirationAction.INVALIDATE; + int regionIdleTimeout = 0; + ExpirationAction regionIdleTimeoutExpirationAction = ExpirationAction.INVALIDATE; + + int entryTimeToLive = 0; + ExpirationAction entryTimeToLiveExpirationAction = ExpirationAction.INVALIDATE; + CustomExpiry customEntryTimeToLive = null; + int entryIdleTimeout = 0; + ExpirationAction entryIdleTimeoutExpirationAction = ExpirationAction.INVALIDATE; + CustomExpiry customEntryIdleTimeout = null; + + Scope scope = AbstractRegion.DEFAULT_SCOPE; + DataPolicy dataPolicy = DataPolicy.DEFAULT; + boolean statisticsEnabled = false; + boolean ignoreJTA = false; + boolean isLockGrantor = false; + Class keyConstraint = null; + Class valueConstraint = null; + int initialCapacity = 16; + float loadFactor = 0.75f; + int concurrencyLevel = 16; + boolean concurrencyChecksEnabled = true; + boolean earlyAck = false; + boolean publisher = false; + boolean enableAsyncConflation = false; + boolean enableSubscriptionConflation = false; + @SuppressWarnings("deprecation") + DiskWriteAttributes diskWriteAttributes = DiskWriteAttributesImpl.getDefaultSyncInstance(); + File[] diskDirs = DiskStoreFactory.DEFAULT_DISK_DIRS; + int[] diskSizes = new int[] {DiskStoreFactory.DEFAULT_DISK_DIR_SIZE}; // 10* 1024 MB } + boolean indexMaintenanceSynchronous = true; + PartitionAttributes partitionAttributes = null; //new PartitionAttributes(); + MembershipAttributes membershipAttributes = new MembershipAttributes(); + SubscriptionAttributes subscriptionAttributes = new SubscriptionAttributes(); + boolean multicastEnabled = false; + EvictionAttributesImpl evictionAttributes = new EvictionAttributesImpl(); // TODO need to determine the constructor + String poolName = null; + String diskStoreName = null; + boolean diskSynchronous = DEFAULT_DISK_SYNCHRONOUS; + protected boolean isBucketRegion = false; + private boolean isCloningEnabled = false; + Compressor compressor = null; + + /** Constructs an instance of RegionAttributes with default settings. + * @see AttributesFactory + */ + public RegionAttributesImpl() { + } + @Override + public String toString() { + StringBuffer buf = new StringBuffer(1000); + buf + .append("RegionAttributes@").append(System.identityHashCode(this)).append(": ") + .append("scope=").append(scope) + .append("; earlyAck=").append(earlyAck) + .append("; publisher=").append(publisher) + .append("; partitionAttrs=").append(partitionAttributes) + .append("; membershipAttrs=").append(membershipAttributes) + .append("; subscriptionAttrs=").append(subscriptionAttributes) + .append("; regionTTL=").append(regionTimeToLive) + .append("; action=").append(regionTimeToLiveExpirationAction) + .append("; regionIdleTimeout=").append(regionIdleTimeout) + .append("; action=").append(regionIdleTimeoutExpirationAction) + .append("; TTL=").append(entryTimeToLive) + .append("; action=").append(entryTimeToLiveExpirationAction) + .append("; custom=").append(customEntryTimeToLive) + .append("; idleTimeout=").append(entryIdleTimeout) + .append("; action=").append(entryIdleTimeoutExpirationAction) + .append("; custom=").append(customEntryIdleTimeout) + .append("; dataPolicy=").append(dataPolicy) + .append("; statisticsEnabled=").append(statisticsEnabled) + .append("; ignoreJTA=").append(ignoreJTA) + .append("; isLockGrantor=").append(isLockGrantor) + .append("; keyConstraint=").append(keyConstraint) + .append("; valueConstraint=").append(valueConstraint) + .append("; initialCapacity=").append(initialCapacity) + .append("; loadFactor=").append(loadFactor) + .append("; concurrencyLevel=").append(concurrencyLevel) + .append("; concurrencyChecksEnabled=").append(concurrencyChecksEnabled) + .append("; enableAsyncConflation=").append(enableAsyncConflation) + .append("; enableSubscriptionConflation=").append(enableSubscriptionConflation) + .append("; isBucketRegion=").append(isBucketRegion) + .append("; poolName=").append(poolName) + .append("; diskSynchronous=").append(diskSynchronous) + .append("; multicastEnabled=").append(multicastEnabled) + .append("; isCloningEnabled=").append(isCloningEnabled) + ; + if (hasDiskWriteAttributes() || hasDiskDirs()) { + buf.append("; diskAttrs=").append(diskWriteAttributes) + .append("; diskDirs=").append(Arrays.toString(diskDirs)) + .append("; diskDirSizes=").append(Arrays.toString(diskSizes)); + } else { + buf.append("; diskStoreName=").append(diskStoreName); + } + buf.append("; GatewaySenderIds=").append(gatewaySenderIds); + buf.append("; AsyncEventQueueIds=").append(asyncEventQueueIds); + buf.append("; compressor=").append(compressor == null ? null : compressor.getClass().getName()); + return buf.toString(); + } + public CacheLoader getCacheLoader() { + return this.cacheLoader; + } + public CacheWriter getCacheWriter() { + return this.cacheWriter; + } + public Class getKeyConstraint() { + return this.keyConstraint; + } + public Class getValueConstraint() { + return this.valueConstraint; + } + private boolean isForBucketRegion() { + return this.isBucketRegion; + } + public ExpirationAttributes getRegionTimeToLive() { + return new ExpirationAttributes( + this.regionTimeToLive, this.regionTimeToLiveExpirationAction); + } + public ExpirationAttributes getRegionIdleTimeout() { + return new ExpirationAttributes( + this.regionIdleTimeout, this.regionIdleTimeoutExpirationAction); + } + + public ExpirationAttributes getEntryTimeToLive() { + return new ExpirationAttributes( + this.entryTimeToLive, this.entryTimeToLiveExpirationAction); + } + public CustomExpiry getCustomEntryTimeToLive() { + return this.customEntryTimeToLive; + } + public ExpirationAttributes getEntryIdleTimeout() { + return new ExpirationAttributes( + this.entryIdleTimeout, this.entryIdleTimeoutExpirationAction); + } + public CustomExpiry getCustomEntryIdleTimeout() { + return this.customEntryIdleTimeout; + } + + @SuppressWarnings("deprecation") + public MirrorType getMirrorType() { + if (this.dataPolicy.isNormal() || this.dataPolicy.isPreloaded() + || this.dataPolicy.isEmpty() || this.dataPolicy.withPartitioning()) { + return MirrorType.NONE; + } else if (this.dataPolicy.withReplication()) { + return MirrorType.KEYS_VALUES; + } else { + throw new IllegalStateException(LocalizedStrings.AttributesFactory_NO_MIRROR_TYPE_CORRESPONDS_TO_DATA_POLICY_0 + .toLocalizedString(this.dataPolicy)); + } + } + public DataPolicy getDataPolicy() { + return this.dataPolicy; + } + public void setDataPolicy(DataPolicy dp) { + this.dataPolicy = dp; + setHasDataPolicy(true); + } + + public Scope getScope() { + return this.scope; + } + public void setScope(Scope s) { + this.scope = s; + setHasScope(true); + } + private static final CacheListener[] EMPTY_LISTENERS = new CacheListener[0]; + @SuppressWarnings("unchecked") + public CacheListener[] getCacheListeners() { + ArrayList> listeners = this.cacheListeners; + if (listeners == null) { + return (CacheListener[])EMPTY_LISTENERS; + } else { + synchronized (listeners) { + if (listeners.size() == 0) { + return (CacheListener[])EMPTY_LISTENERS; + } else { + CacheListener[] result = new CacheListener[listeners.size()]; + listeners.toArray(result); + return result; + } + } + } + } + public CacheListener getCacheListener() { + ArrayList> listeners = this.cacheListeners; + if (listeners == null) { + return null; + } + synchronized (listeners) { + if (listeners.size() == 0) { + return null; + } + if (listeners.size() == 1) { + return this.cacheListeners.get(0); + } + } + throw new IllegalStateException(LocalizedStrings.AttributesFactory_MORE_THAN_ONE_CACHE_LISTENER_EXISTS.toLocalizedString()); + } + protected void addCacheListener(CacheListener aListener) { + ArrayList> listeners = this.cacheListeners; + if (listeners == null) { + ArrayList> al = new ArrayList>(1); + al.add(aListener); + this.cacheListeners = al; + } else { + synchronized (listeners) { + listeners.add(aListener); + } + } + setHasCacheListeners(true); + } + + public void addGatewaySenderId(String gatewaySenderId) { + if(this.gatewaySenderIds == null){ + this.gatewaySenderIds = new CopyOnWriteArraySet(); + this.gatewaySenderIds.add(gatewaySenderId); + }else{ + synchronized (this.gatewaySenderIds) { // TODO: revisit this + // synchronization : added as per + // above code + if (this.gatewaySenderIds.contains(gatewaySenderId)) { + throw new IllegalArgumentException( + LocalizedStrings.AttributesFactory_GATEWAY_SENDER_ID_0_IS_ALREADY_ADDED + .toLocalizedString(gatewaySenderId)); + } + this.gatewaySenderIds.add(gatewaySenderId); + } + } + setHasGatewaySenderIds(true); + } + + public void addAsyncEventQueueId(String asyncEventQueueId) { + if(this.asyncEventQueueIds == null){ + this.asyncEventQueueIds = new CopyOnWriteArraySet(); + this.asyncEventQueueIds.add(asyncEventQueueId); + } else{ + synchronized (this.asyncEventQueueIds) { // TODO: revisit this + // synchronization : added as per + // above code + if (this.asyncEventQueueIds.contains(asyncEventQueueId)) { + throw new IllegalArgumentException( + LocalizedStrings.AttributesFactory_ASYNC_EVENT_QUEUE_ID_0_IS_ALREADY_ADDED + .toLocalizedString(asyncEventQueueId)); + } + this.asyncEventQueueIds.add(asyncEventQueueId); + } + } + setHasAsyncEventListeners(true); + } + + public int getInitialCapacity() { + return this.initialCapacity; + } + public float getLoadFactor() { + return this.loadFactor; + } + public boolean getStatisticsEnabled() { + return this.statisticsEnabled; + } + public boolean getIgnoreJTA() { + return this.ignoreJTA; + } + public boolean isLockGrantor() { + return this.isLockGrantor; + } + public int getConcurrencyLevel() { + return this.concurrencyLevel; + } + public boolean getConcurrencyChecksEnabled() { + return this.concurrencyChecksEnabled; + } + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public Object clone() { + try { + RegionAttributesImpl copy = (RegionAttributesImpl) super.clone(); + if (copy.getIndexes() != null) { + copy.setIndexes(new ArrayList(copy.getIndexes())); + } + if (copy.partitionAttributes != null) { + copy.partitionAttributes = ((PartitionAttributesImpl)copy.partitionAttributes).copy(); + } + if (copy.cacheListeners != null) { + copy.cacheListeners = new ArrayList>(copy.cacheListeners); + } + if (copy.gatewaySenderIds != null) { + copy.gatewaySenderIds = new CopyOnWriteArraySet(copy.gatewaySenderIds); + } + if (copy.asyncEventQueueIds != null) { + copy.asyncEventQueueIds = new CopyOnWriteArraySet(copy.asyncEventQueueIds); + } + return copy; + } + catch (CloneNotSupportedException e) { + throw new InternalError(LocalizedStrings.AttributesFactory_CLONENOTSUPPORTEDEXCEPTION_THROWN_IN_CLASS_THAT_IMPLEMENTS_CLONEABLE.toLocalizedString()); + } + } + + public boolean getPersistBackup() { + return getDataPolicy().withPersistence(); + } + + public boolean getEarlyAck() { + return this.earlyAck; + } + + /* + * @deprecated as of 6.5 + */ + @Deprecated + public boolean getPublisher() { + return this.publisher; + } + + public boolean getEnableConflation() { // deprecated in 5.0 + return getEnableSubscriptionConflation(); + } + + public boolean getEnableAsyncConflation() { + return this.enableAsyncConflation; + } + + public boolean getEnableBridgeConflation() { // deprecated in 5.7 + return getEnableSubscriptionConflation(); + } + + public boolean getEnableSubscriptionConflation() { + return this.enableSubscriptionConflation; + } + + /** + * @deprecated as of 6.5 + */ + @Deprecated + public DiskWriteAttributes getDiskWriteAttributes() { + if (this.diskStoreName != null) { + throw new IllegalStateException(LocalizedStrings.DiskStore_Deprecated_API_0_Cannot_Mix_With_DiskStore_1 + .toLocalizedString(new Object[] {"getDiskWriteAttributes", this.diskStoreName})); + } + return this.diskWriteAttributes; + } + + /** + * @deprecated as of 6.5 + */ + @Deprecated + public File[] getDiskDirs() { + if (this.diskStoreName != null) { + throw new IllegalStateException(LocalizedStrings.DiskStore_Deprecated_API_0_Cannot_Mix_With_DiskStore_1 + .toLocalizedString(new Object[] {"getDiskDirs", this.diskStoreName})); + } + return this.diskDirs; + } + + public boolean getIndexMaintenanceSynchronous() { + return this.indexMaintenanceSynchronous; + } + + public PartitionAttributes getPartitionAttributes() { + return this.partitionAttributes; + } + public EvictionAttributes getEvictionAttributes() + { + return this.evictionAttributes; + } + public MembershipAttributes getMembershipAttributes() { + retur