PageRenderTime 46ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/jboss-as-7.1.1.Final/web/src/main/java/org/jboss/as/web/session/AttributeBasedClusteredSession.java

#
Java | 180 lines | 102 code | 27 blank | 51 comment | 18 complexity | c0bd8351b839078735c476e8ca8772b8 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0
  1. /*
  2. * JBoss, Home of Professional Open Source.
  3. * Copyright 2008, Red Hat Middleware LLC, and individual contributors
  4. * as indicated by the @author tags. See the copyright.txt file in the
  5. * distribution for a full listing of individual contributors.
  6. *
  7. * This is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU Lesser General Public License as
  9. * published by the Free Software Foundation; either version 2.1 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This software is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this software; if not, write to the Free
  19. * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20. * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  21. */
  22. package org.jboss.as.web.session;
  23. import java.util.HashMap;
  24. import java.util.HashSet;
  25. import java.util.Map;
  26. import java.util.Set;
  27. import org.jboss.as.clustering.web.DistributableSessionMetadata;
  28. import org.jboss.as.clustering.web.OutgoingAttributeGranularitySessionData;
  29. /**
  30. * Implementation of a clustered session where the replication granularity level is attribute based; that is, we replicate only
  31. * the dirty attributes.
  32. * <p/>
  33. * Note that the isolation level of the cache dictates the concurrency behavior. Also note that session and its associated
  34. * attributes are stored in different nodes. This will be ok since cache will take care of concurrency. When replicating, we
  35. * will need to replicate both session and its attributes.
  36. * </p>
  37. * @author Ben Wang
  38. * @author Brian Stansberry
  39. */
  40. class AttributeBasedClusteredSession extends ClusteredSession<OutgoingAttributeGranularitySessionData> {
  41. static final long serialVersionUID = -5625209785550936713L;
  42. /**
  43. * Descriptive information describing this Session implementation.
  44. */
  45. protected static final String info = "AttributeBasedClusteredSession/1.0";
  46. // Transient map to store attr changes for replication.
  47. private transient Map<String, Object> attrModifiedMap_ = new HashMap<String, Object>();
  48. // Transient set to store attr removals for replication
  49. private transient Set<String> attrRemovedSet_ = new HashSet<String>();
  50. // ------------------------------------------------------------ Constructors
  51. public AttributeBasedClusteredSession(ClusteredSessionManager<OutgoingAttributeGranularitySessionData> manager) {
  52. super(manager);
  53. }
  54. // ----------------------------------------------- Overridden Public Methods
  55. @Override
  56. public String getInfo() {
  57. return (info);
  58. }
  59. /**
  60. * Override the superclass to additionally reset this class' fields.
  61. * <p>
  62. * <strong>NOTE:</strong> It is not anticipated that this method will be called on a ClusteredSession, but we are overriding
  63. * the method to be thorough.
  64. * </p>
  65. */
  66. @Override
  67. public void recycle() {
  68. super.recycle();
  69. clearAttrChangedMaps();
  70. }
  71. // -------------------------------------------- Overridden Protected Methods
  72. @Override
  73. protected OutgoingAttributeGranularitySessionData getOutgoingSessionData() {
  74. Map<String, Object> modAttrs = null;
  75. Set<String> removeAttrs = null;
  76. if (isSessionAttributeMapDirty()) {
  77. if (attrModifiedMap_.size() > 0) {
  78. modAttrs = new HashMap<String, Object>(attrModifiedMap_);
  79. }
  80. if (attrRemovedSet_.size() > 0) {
  81. removeAttrs = new HashSet<String>(attrRemovedSet_);
  82. }
  83. clearAttrChangedMaps();
  84. }
  85. DistributableSessionMetadata metadata = isSessionMetadataDirty() ? getSessionMetadata() : null;
  86. Long timestamp = modAttrs != null || removeAttrs != null || metadata != null || getMustReplicateTimestamp() ? Long
  87. .valueOf(getSessionTimestamp()) : null;
  88. return new OutgoingData(getRealId(), getVersion(), timestamp, metadata, modAttrs, removeAttrs);
  89. }
  90. @Override
  91. protected Object getAttributeInternal(String name) {
  92. Object result = getAttributesInternal().get(name);
  93. // Do dirty check even if result is null, as w/ SET_AND_GET null
  94. // still makes us dirty (ensures timely replication w/o using ACCESS)
  95. if (isGetDirty(result) && !replicationExcludes.contains(name)) {
  96. attributeChanged(name, result, false);
  97. }
  98. return result;
  99. }
  100. @Override
  101. protected Object removeAttributeInternal(String name, boolean localCall, boolean localOnly) {
  102. Object result = getAttributesInternal().remove(name);
  103. if (localCall && !replicationExcludes.contains(name))
  104. attributeChanged(name, result, true);
  105. return result;
  106. }
  107. @Override
  108. protected Object setAttributeInternal(String key, Object value) {
  109. Object old = getAttributesInternal().put(key, value);
  110. if (!replicationExcludes.contains(key))
  111. attributeChanged(key, value, false);
  112. return old;
  113. }
  114. // ------------------------------------------------------- Private Methods
  115. private synchronized void attributeChanged(String key, Object value, boolean removal) {
  116. if (removal) {
  117. if (attrModifiedMap_.containsKey(key)) {
  118. attrModifiedMap_.remove(key);
  119. }
  120. attrRemovedSet_.add(key);
  121. } else {
  122. if (attrRemovedSet_.contains(key)) {
  123. attrRemovedSet_.remove(key);
  124. }
  125. attrModifiedMap_.put(key, value);
  126. }
  127. sessionAttributesDirty();
  128. }
  129. private synchronized void clearAttrChangedMaps() {
  130. attrRemovedSet_.clear();
  131. attrModifiedMap_.clear();
  132. }
  133. // ----------------------------------------------------------------- Classes
  134. private static class OutgoingData extends OutgoingDistributableSessionDataImpl implements
  135. OutgoingAttributeGranularitySessionData {
  136. private final Map<String, Object> modifiedAttributes;
  137. private final Set<String> removedAttributes;
  138. public OutgoingData(String realId, int version, Long timestamp, DistributableSessionMetadata metadata,
  139. Map<String, Object> modifiedAttributes, Set<String> removedAttributes) {
  140. super(realId, version, timestamp, metadata);
  141. this.modifiedAttributes = modifiedAttributes;
  142. this.removedAttributes = removedAttributes;
  143. }
  144. @Override
  145. public Map<String, Object> getModifiedSessionAttributes() {
  146. return modifiedAttributes;
  147. }
  148. @Override
  149. public Set<String> getRemovedSessionAttributes() {
  150. return removedAttributes;
  151. }
  152. }
  153. }