Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (c) 2008-2016, Hazelcast, Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hazelcast.web;
import com.hazelcast.nio.serialization.HazelcastSerializationException;
import com.hazelcast.util.EmptyStatement;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionContext;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* HazelcastHttpSession is HttpSession implementation based on Hazelcast Imap.
* It contains the methods used to get, put, manage the current state of the HttpSession.
*/
public class HazelcastHttpSession implements HttpSession {
volatile String invalidatedOriginalSessionId;
private WebFilter webFilter;
private volatile boolean valid = true;
private final String id;
private final HttpSession originalSession;
private final Map localCache = new ConcurrentHashMap();
private final boolean stickySession;
private final boolean deferredWrite;
// only true if session is created first time in the cluster
private volatile boolean clusterWideNew;
private Set transientAttributes;
public HazelcastHttpSession(WebFilter webFilter, final String sessionId, final HttpSession originalSession,
final boolean deferredWrite, final boolean stickySession,
final Set transientAttributes) {
this.webFilter = webFilter;
this.id = sessionId;
this.originalSession = originalSession;
this.deferredWrite = deferredWrite;
this.stickySession = stickySession;
this.transientAttributes = transientAttributes;
buildLocalCache();
}
public HttpSession getOriginalSession() {
return originalSession;
}
public String getOriginalSessionId() {
return originalSession != null ? originalSession.getId() : null;
}
public void setAttribute(final String name, final Object value) {
if (name == null) {
throw new NullPointerException("name must not be null");
}
if (value == null) {
removeAttribute(name);
return;
}
boolean transientEntry = false;
if (transientAttributes.contains(name)) {
transientEntry = true;
}
LocalCacheEntry entry = localCache.get(name);
if (entry == null || entry == WebFilter.NULL_ENTRY) {
entry = new LocalCacheEntry(transientEntry);
localCache.put(name, entry);
}
entry.setValue(value);
entry.setDirty(true);
entry.setRemoved(false);
entry.setReload(false);
if (!deferredWrite && !transientEntry) {
try {
webFilter.getClusteredSessionService().setAttribute(id, name, value);
entry.setDirty(false);
} catch (HazelcastSerializationException e) {
WebFilter.LOGGER.warning("Failed to serialize attribute [" + name + "]:" + e.getMessage(), e);
} catch (Exception ignored) {
EmptyStatement.ignore(ignored);
}
}
}
public Object getAttribute(final String name) {
LocalCacheEntry cacheEntry = localCache.get(name);
Object value = null;
if (cacheEntry == null || cacheEntry.isReload()) {
try {
value = webFilter.getClusteredSessionService().getAttribute(id, name);
cacheEntry = new LocalCacheEntry(false, value);
cacheEntry.setReload(false);
localCache.put(name, cacheEntry);
} catch (Exception e) {
if (WebFilter.LOGGER.isFinestEnabled()) {
WebFilter.LOGGER.finest("session could not be load so you might be dealing with stale data", e);
}
if (cacheEntry == null) {
return null;
}
}
}
if (cacheEntry.isRemoved()) {
return null;
}
return cacheEntry.getValue();
}
public Enumeration getAttributeNames() {
final Set keys = selectKeys();
return new Enumeration() {
private final String[] elements = keys.toArray(new String[keys.size()]);
private int index;
@Override
public boolean hasMoreElements() {
return index < elements.length;
}
@Override
public String nextElement() {
return elements[index++];
}
};
}
public String getId() {
return id;
}
public ServletContext getServletContext() {
return webFilter.servletContext;
}
@Deprecated
@SuppressWarnings("deprecation")
public HttpSessionContext getSessionContext() {
return originalSession.getSessionContext();
}
public Object getValue(final String name) {
return getAttribute(name);
}
public String[] getValueNames() {
final Set keys = selectKeys();
return keys.toArray(new String[keys.size()]);
}
public void invalidate() {
// we must invalidate hazelcast session first
// invalidating original session will trigger another
// invalidation as our SessionListener will be triggered.
webFilter.destroySession(this, true);
originalSession.invalidate();
invalidatedOriginalSessionId = originalSession.getId();
}
public boolean isNew() {
return originalSession.isNew() && clusterWideNew;
}
public void putValue(final String name, final Object value) {
setAttribute(name, value);
}
public void removeAttribute(final String name) {
LocalCacheEntry entry = localCache.get(name);
if (entry != null && entry != WebFilter.NULL_ENTRY) {
entry.setValue(null);
entry.setRemoved(true);
entry.setDirty(true);
entry.setReload(false);
}
if (!deferredWrite) {
try {
webFilter.getClusteredSessionService().deleteAttribute(id, name);
entry.setDirty(false);
} catch (Exception ignored) {
EmptyStatement.ignore(ignored);
}
}
}
public void removeValue(final String name) {
removeAttribute(name);
}
/**
* @return {@code true} if {@link #deferredWrite} is enabled and at least one entry in the local
* cache is dirty; otherwise, {@code false}
*/
public boolean sessionChanged() {
for (Map.Entry entry : localCache.entrySet()) {
if (entry.getValue().isDirty()) {
return true;
}
}
return false;
}
public long getCreationTime() {
return originalSession.getCreationTime();
}
public long getLastAccessedTime() {
return originalSession.getLastAccessedTime();
}
public int getMaxInactiveInterval() {
return originalSession.getMaxInactiveInterval();
}
public void setMaxInactiveInterval(int maxInactiveSeconds) {
originalSession.setMaxInactiveInterval(maxInactiveSeconds);
}
void destroy(boolean invalidate) {
valid = false;
webFilter.getClusteredSessionService().deleteSession(id, invalidate);
}
public boolean isValid() {
return valid;
}
private void buildLocalCache() {
Set> entrySet = null;
try {
entrySet = webFilter.getClusteredSessionService().getAttributes(id);
} catch (Exception e) {
return;
}
if (entrySet != null) {
for (Map.Entry entry : entrySet) {
String attributeKey = entry.getKey();
LocalCacheEntry cacheEntry = localCache.get(attributeKey);
if (cacheEntry == null) {
cacheEntry = new LocalCacheEntry(transientAttributes.contains(attributeKey));
localCache.put(attributeKey, cacheEntry);
}
if (WebFilter.LOGGER.isFinestEnabled()) {
WebFilter.LOGGER.finest("Storing " + attributeKey + " on session " + id);
}
cacheEntry.setValue(entry.getValue());
cacheEntry.setDirty(false);
}
}
}
void sessionDeferredWrite() {
if (sessionChanged() || isNew()) {
Map updates = new HashMap();
Iterator> iterator = localCache.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = iterator.next();
LocalCacheEntry cacheEntry = entry.getValue();
if (cacheEntry.isDirty() && !cacheEntry.isTransient()) {
if (cacheEntry.isRemoved()) {
updates.put(entry.getKey(), null);
} else {
updates.put(entry.getKey(), cacheEntry.getValue());
}
cacheEntry.setDirty(false);
}
}
try {
webFilter.getClusteredSessionService().updateAttributes(id, updates);
} catch (Exception ignored) {
EmptyStatement.ignore(ignored);
}
}
}
private Set selectKeys() {
Set keys = new HashSet();
if (!deferredWrite) {
Set attributeNames = null;
try {
attributeNames = webFilter.getClusteredSessionService().getAttributeNames(id);
} catch (Exception ignored) {
for (Map.Entry entry : localCache.entrySet()) {
if (!entry.getValue().isRemoved() && entry.getValue().getValue() != null) {
keys.add(entry.getKey());
}
}
}
if (attributeNames != null) {
keys.addAll(attributeNames);
}
} else {
for (Map.Entry entry : localCache.entrySet()) {
if (!entry.getValue().isRemoved() && entry.getValue().getValue() != null) {
keys.add(entry.getKey());
}
}
}
return keys;
}
public void setClusterWideNew(boolean clusterWideNew) {
this.clusterWideNew = clusterWideNew;
}
public boolean isStickySession() {
return stickySession;
}
public void updateReloadFlag() {
for (Map.Entry entry : localCache.entrySet()) {
if (!entry.getValue().isDirty()) {
entry.getValue().setReload(true);
}
}
}
} // END of HazelSession