1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.eclipse.jetty.server.session;
16
17 import java.io.ByteArrayInputStream;
18 import java.io.ByteArrayOutputStream;
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.io.ObjectInputStream;
22 import java.io.ObjectOutputStream;
23 import java.sql.Connection;
24 import java.sql.PreparedStatement;
25 import java.sql.ResultSet;
26 import java.sql.SQLException;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.ListIterator;
30 import java.util.Map;
31 import java.util.concurrent.ConcurrentHashMap;
32 import java.util.concurrent.atomic.AtomicReference;
33
34 import javax.servlet.http.HttpServletRequest;
35 import javax.servlet.http.HttpSessionEvent;
36 import javax.servlet.http.HttpSessionListener;
37
38 import org.eclipse.jetty.server.SessionIdManager;
39 import org.eclipse.jetty.server.handler.ContextHandler;
40 import org.eclipse.jetty.util.log.Log;
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 public class JDBCSessionManager extends AbstractSessionManager
67 {
68 protected String __insertSession;
69 protected String __deleteSession;
70 protected String __selectSession;
71 protected String __updateSession;
72 protected String __updateSessionNode;
73 protected String __updateSessionAccessTime;
74 protected String __sessionTableRowId;
75
76 private ConcurrentHashMap<String, AbstractSession> _sessions;
77 protected long _saveIntervalSec = 60;
78
79
80
81
82
83
84 public class SessionData
85 {
86 private final String _id;
87 private String _rowId;
88 private long _accessed;
89 private long _lastAccessed;
90 private long _maxIdleMs=-1;
91 private long _cookieSet;
92 private long _created;
93 private Map<String,Object> _attributes;
94 private String _lastNode;
95 private String _canonicalContext;
96 private long _lastSaved;
97 private long _expiryTime;
98 private String _virtualHost;
99
100 public SessionData (String sessionId)
101 {
102 _id=sessionId;
103 _created=System.currentTimeMillis();
104 _accessed = _created;
105 _attributes = new HashMap<String,Object>();
106 _lastNode = getSessionIdManager().getWorkerName();
107 }
108
109 public SessionData (String sessionId,Map<String,Object> attributes)
110 {
111 _id=sessionId;
112 _created=System.currentTimeMillis();
113 _accessed = _created;
114 _attributes = attributes;
115 _lastNode = getSessionIdManager().getWorkerName();
116 }
117
118 public synchronized String getId ()
119 {
120 return _id;
121 }
122
123 public synchronized long getCreated ()
124 {
125 return _created;
126 }
127
128 protected synchronized void setCreated (long ms)
129 {
130 _created = ms;
131 }
132
133 public synchronized long getAccessed ()
134 {
135 return _accessed;
136 }
137
138 protected synchronized void setAccessed (long ms)
139 {
140 _accessed = ms;
141 }
142
143
144 public synchronized void setMaxIdleMs (long ms)
145 {
146 _maxIdleMs = ms;
147 }
148
149 public synchronized long getMaxIdleMs()
150 {
151 return _maxIdleMs;
152 }
153
154 public synchronized void setLastAccessed (long ms)
155 {
156 _lastAccessed = ms;
157 }
158
159 public synchronized long getLastAccessed()
160 {
161 return _lastAccessed;
162 }
163
164 public void setCookieSet (long ms)
165 {
166 _cookieSet = ms;
167 }
168
169 public synchronized long getCookieSet ()
170 {
171 return _cookieSet;
172 }
173
174 public synchronized void setRowId (String rowId)
175 {
176 _rowId=rowId;
177 }
178
179 protected synchronized String getRowId()
180 {
181 return _rowId;
182 }
183
184 protected synchronized Map<String,Object> getAttributeMap ()
185 {
186 return _attributes;
187 }
188
189 protected synchronized void setAttributeMap (Map<String,Object> map)
190 {
191 _attributes = map;
192 }
193
194 public synchronized void setLastNode (String node)
195 {
196 _lastNode=node;
197 }
198
199 public synchronized String getLastNode ()
200 {
201 return _lastNode;
202 }
203
204 public synchronized void setCanonicalContext(String str)
205 {
206 _canonicalContext=str;
207 }
208
209 public synchronized String getCanonicalContext ()
210 {
211 return _canonicalContext;
212 }
213
214 public synchronized long getLastSaved ()
215 {
216 return _lastSaved;
217 }
218
219 public synchronized void setLastSaved (long time)
220 {
221 _lastSaved=time;
222 }
223
224 public synchronized void setExpiryTime (long time)
225 {
226 _expiryTime=time;
227 }
228
229 public synchronized long getExpiryTime ()
230 {
231 return _expiryTime;
232 }
233
234 public synchronized void setVirtualHost (String vhost)
235 {
236 _virtualHost=vhost;
237 }
238
239 public synchronized String getVirtualHost ()
240 {
241 return _virtualHost;
242 }
243
244 @Override
245 public String toString ()
246 {
247 return "Session rowId="+_rowId+",id="+_id+",lastNode="+_lastNode+
248 ",created="+_created+",accessed="+_accessed+
249 ",lastAccessed="+_lastAccessed+",cookieSet="+_cookieSet+
250 "lastSaved="+_lastSaved;
251 }
252 }
253
254
255
256
257
258
259
260
261 public class Session extends AbstractSession
262 {
263 private static final long serialVersionUID = 5208464051134226143L;
264 private final SessionData _data;
265 private boolean _dirty=false;
266
267
268
269
270
271
272 protected Session (HttpServletRequest request)
273 {
274 super(JDBCSessionManager.this,request);
275 _data = new SessionData(getClusterId(),_jdbcAttributes);
276 if (_dftMaxIdleSecs>0)
277 _data.setMaxIdleMs(_dftMaxIdleSecs*1000);
278 _data.setCanonicalContext(canonicalize(_context.getContextPath()));
279 _data.setVirtualHost(getVirtualHost(_context));
280 int maxInterval=getMaxInactiveInterval();
281 _data.setExpiryTime(maxInterval <= 0 ? 0 : (System.currentTimeMillis() + maxInterval*1000));
282 }
283
284
285
286
287
288 protected Session (long accessed, SessionData data)
289 {
290 super(JDBCSessionManager.this,data.getCreated(), accessed, data.getId());
291 _data=data;
292 if (_dftMaxIdleSecs>0)
293 _data.setMaxIdleMs(_dftMaxIdleSecs*1000);
294 _jdbcAttributes.putAll(_data.getAttributeMap());
295 _data.setAttributeMap(_jdbcAttributes);
296 }
297
298 @Override
299 public void setAttribute (String name, Object value)
300 {
301 super.setAttribute(name, value);
302 _dirty=true;
303 }
304
305 @Override
306 public void removeAttribute (String name)
307 {
308 super.removeAttribute(name);
309 _dirty=true;
310 }
311
312 @Override
313 protected void cookieSet()
314 {
315 _data.setCookieSet(_data.getAccessed());
316 }
317
318
319
320
321
322
323
324 @Override
325 protected boolean access(long time)
326 {
327 if (super.access(time))
328 {
329 _data.setLastAccessed(_data.getAccessed());
330 _data.setAccessed(time);
331
332 int maxInterval=getMaxInactiveInterval();
333 _data.setExpiryTime(maxInterval <= 0 ? 0 : (time + maxInterval*1000));
334 return true;
335 }
336 return false;
337 }
338
339
340
341
342
343 @Override
344 protected void complete()
345 {
346 super.complete();
347 try
348 {
349 if (_dirty)
350 {
351
352
353 willPassivate();
354 updateSession(_data);
355 didActivate();
356 }
357 else if ((_data._accessed - _data._lastSaved) >= (getSaveInterval() * 1000))
358 {
359 updateSessionAccessTime(_data);
360 }
361 }
362 catch (Exception e)
363 {
364 Log.warn("Problem persisting changed session data id="+getId(), e);
365 }
366 finally
367 {
368 _dirty=false;
369 }
370 }
371
372 @Override
373 protected void timeout() throws IllegalStateException
374 {
375 if (Log.isDebugEnabled()) Log.debug("Timing out session id="+getClusterId());
376 super.timeout();
377 }
378 }
379
380
381
382
383
384
385
386
387
388 protected class ClassLoadingObjectInputStream extends ObjectInputStream
389 {
390 public ClassLoadingObjectInputStream(java.io.InputStream in) throws IOException
391 {
392 super(in);
393 }
394
395 public ClassLoadingObjectInputStream () throws IOException
396 {
397 super();
398 }
399
400 @Override
401 public Class<?> resolveClass (java.io.ObjectStreamClass cl) throws IOException, ClassNotFoundException
402 {
403 try
404 {
405 return Class.forName(cl.getName(), false, Thread.currentThread().getContextClassLoader());
406 }
407 catch (ClassNotFoundException e)
408 {
409 return super.resolveClass(cl);
410 }
411 }
412 }
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435 public void setSaveInterval (long sec)
436 {
437 _saveIntervalSec=sec;
438 }
439
440 public long getSaveInterval ()
441 {
442 return _saveIntervalSec;
443 }
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458 public void cacheInvalidate (Session session)
459 {
460
461 }
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480 @Override
481 public Session getSession(String idInCluster)
482 {
483 Session session = (Session)_sessions.get(idInCluster);
484
485 synchronized (this)
486 {
487 try
488 {
489
490
491
492
493
494
495
496
497 SessionData data = null;
498 long now = System.currentTimeMillis();
499 if (Log.isDebugEnabled())
500 {
501 if (session==null)
502 Log.debug("getSession("+idInCluster+"): not in session map,"+
503 " now="+now+
504 " lastSaved="+(session==null?0:session._data._lastSaved)+
505 " interval="+(_saveIntervalSec * 1000));
506 else
507 Log.debug("getSession("+idInCluster+"): in session map, "+
508 " now="+now+
509 " lastSaved="+(session==null?0:session._data._lastSaved)+
510 " interval="+(_saveIntervalSec * 1000)+
511 " lastNode="+session._data.getLastNode()+
512 " thisNode="+getSessionIdManager().getWorkerName()+
513 " difference="+(now - session._data._lastSaved));
514 }
515
516 if (session==null || ((now - session._data._lastSaved) >= (_saveIntervalSec * 1000)))
517 {
518 Log.debug("getSession("+idInCluster+"): no session in session map or stale session. Reloading session data from db.");
519 data = loadSession(idInCluster, canonicalize(_context.getContextPath()), getVirtualHost(_context));
520 }
521 else if ((now - session._data._lastSaved) >= (_saveIntervalSec * 1000))
522 {
523 Log.debug("getSession("+idInCluster+"): stale session. Reloading session data from db.");
524 data = loadSession(idInCluster, canonicalize(_context.getContextPath()), getVirtualHost(_context));
525 }
526 else
527 {
528 Log.debug("getSession("+idInCluster+"): session in session map");
529 data = session._data;
530 }
531
532 if (data != null)
533 {
534 if (!data.getLastNode().equals(getSessionIdManager().getWorkerName()) || session==null)
535 {
536
537 if (data._expiryTime <= 0 || data._expiryTime > now)
538 {
539 Log.debug("getSession("+idInCluster+"): lastNode="+data.getLastNode()+" thisNode="+getSessionIdManager().getWorkerName());
540 data.setLastNode(getSessionIdManager().getWorkerName());
541
542 session = new Session(now,data);
543 _sessions.put(idInCluster, session);
544 session.didActivate();
545
546
547 updateSessionNode(data);
548 }
549 else
550 if (Log.isDebugEnabled()) Log.debug("getSession("+idInCluster+"): Session has expired");
551
552 }
553 else
554 if (Log.isDebugEnabled()) Log.debug("getSession("+idInCluster+"): Session not stale "+session._data);
555
556 }
557 else
558 {
559
560 session=null;
561 if (Log.isDebugEnabled()) Log.debug("getSession("+idInCluster+"): No session in database matching id="+idInCluster);
562 }
563
564 return session;
565 }
566 catch (Exception e)
567 {
568 Log.warn("Unable to load session from database", e);
569 return null;
570 }
571 }
572 }
573
574
575
576
577
578
579 @Override
580 public int getSessions()
581 {
582 int size = 0;
583 synchronized (this)
584 {
585 size = _sessions.size();
586 }
587 return size;
588 }
589
590
591
592
593
594
595
596 @Override
597 public void doStart() throws Exception
598 {
599 if (_sessionIdManager==null)
600 throw new IllegalStateException("No session id manager defined");
601
602 prepareTables();
603
604 _sessions = new ConcurrentHashMap<String, AbstractSession>();
605 super.doStart();
606 }
607
608
609
610
611
612
613
614 @Override
615 public void doStop() throws Exception
616 {
617 _sessions.clear();
618 _sessions = null;
619
620 super.doStop();
621 }
622
623 @Override
624 protected void invalidateSessions()
625 {
626
627
628
629
630
631
632 }
633
634
635
636
637
638
639
640 protected void invalidateSession (String idInCluster)
641 {
642 Session session = null;
643 synchronized (this)
644 {
645 session = (Session)_sessions.get(idInCluster);
646 }
647
648 if (session != null)
649 {
650 session.invalidate();
651 }
652 }
653
654
655
656
657
658
659
660 @Override
661 protected boolean removeSession(String idInCluster)
662 {
663 synchronized (this)
664 {
665 Session session = (Session)_sessions.remove(idInCluster);
666 try
667 {
668 if (session != null)
669 deleteSession(session._data);
670 }
671 catch (Exception e)
672 {
673 Log.warn("Problem deleting session id="+idInCluster, e);
674 }
675 return session!=null;
676 }
677 }
678
679
680
681
682
683
684
685 @Override
686 protected void addSession(AbstractSession session)
687 {
688 if (session==null)
689 return;
690
691 synchronized (this)
692 {
693 _sessions.put(session.getClusterId(), session);
694 }
695
696
697
698 try
699 {
700 session.willPassivate();
701 storeSession(((JDBCSessionManager.Session)session)._data);
702 session.didActivate();
703 }
704 catch (Exception e)
705 {
706 Log.warn("Unable to store new session id="+session.getId() , e);
707 }
708 }
709
710
711
712
713
714
715
716 @Override
717 protected AbstractSession newSession(HttpServletRequest request)
718 {
719 return new Session(request);
720 }
721
722
723
724
725
726
727
728 @Override
729 public void removeSession(AbstractSession session, boolean invalidate)
730 {
731
732 boolean removed = false;
733
734 synchronized (this)
735 {
736
737 if (getSession(session.getClusterId()) != null)
738 {
739 removed = true;
740 removeSession(session.getClusterId());
741 }
742 }
743
744 if (removed)
745 {
746
747 _sessionIdManager.removeSession(session);
748
749 if (invalidate)
750 _sessionIdManager.invalidateAll(session.getClusterId());
751
752 if (invalidate && !_sessionListeners.isEmpty())
753 {
754 HttpSessionEvent event=new HttpSessionEvent(session);
755 for (HttpSessionListener l : _sessionListeners)
756 l.sessionDestroyed(event);
757 }
758 if (!invalidate)
759 {
760 session.willPassivate();
761 }
762 }
763 }
764
765
766
767
768
769
770
771
772 protected void expire (List<?> sessionIds)
773 {
774
775 if (isStopping() || isStopped())
776 return;
777
778
779 Thread thread=Thread.currentThread();
780 ClassLoader old_loader=thread.getContextClassLoader();
781 ListIterator<?> itor = sessionIds.listIterator();
782
783 try
784 {
785 while (itor.hasNext())
786 {
787 String sessionId = (String)itor.next();
788 if (Log.isDebugEnabled()) Log.debug("Expiring session id "+sessionId);
789
790 Session session = (Session)_sessions.get(sessionId);
791 if (session != null)
792 {
793 session.timeout();
794 itor.remove();
795 }
796 else
797 {
798 if (Log.isDebugEnabled()) Log.debug("Unrecognized session id="+sessionId);
799 }
800 }
801 }
802 catch (Throwable t)
803 {
804 if (t instanceof ThreadDeath)
805 throw ((ThreadDeath)t);
806 else
807 Log.warn("Problem expiring sessions", t);
808 }
809 finally
810 {
811 thread.setContextClassLoader(old_loader);
812 }
813 }
814
815
816 protected void prepareTables ()
817 {
818 __sessionTableRowId = ((JDBCSessionIdManager)_sessionIdManager)._sessionTableRowId;
819
820 __insertSession = "insert into "+((JDBCSessionIdManager)_sessionIdManager)._sessionTable+
821 " ("+__sessionTableRowId+", sessionId, contextPath, virtualHost, lastNode, accessTime, lastAccessTime, createTime, cookieTime, lastSavedTime, expiryTime, map) "+
822 " values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
823
824 __deleteSession = "delete from "+((JDBCSessionIdManager)_sessionIdManager)._sessionTable+
825 " where "+__sessionTableRowId+" = ?";
826
827 __selectSession = "select * from "+((JDBCSessionIdManager)_sessionIdManager)._sessionTable+
828 " where sessionId = ? and contextPath = ? and virtualHost = ?";
829
830 __updateSession = "update "+((JDBCSessionIdManager)_sessionIdManager)._sessionTable+
831 " set lastNode = ?, accessTime = ?, lastAccessTime = ?, lastSavedTime = ?, expiryTime = ?, map = ? where "+__sessionTableRowId+" = ?";
832
833 __updateSessionNode = "update "+((JDBCSessionIdManager)_sessionIdManager)._sessionTable+
834 " set lastNode = ? where "+__sessionTableRowId+" = ?";
835
836 __updateSessionAccessTime = "update "+((JDBCSessionIdManager)_sessionIdManager)._sessionTable+
837 " set lastNode = ?, accessTime = ?, lastAccessTime = ?, lastSavedTime = ?, expiryTime = ? where "+__sessionTableRowId+" = ?";
838 }
839
840
841
842
843
844
845
846 protected SessionData loadSession (final String id, final String canonicalContextPath, final String vhost)
847 throws Exception
848 {
849 final AtomicReference<SessionData> _reference = new AtomicReference<SessionData>();
850 final AtomicReference<Exception> _exception = new AtomicReference<Exception>();
851 Runnable load = new Runnable()
852 {
853 @SuppressWarnings("unchecked")
854 public void run()
855 {
856 SessionData data = null;
857 Connection connection=null;
858 PreparedStatement statement = null;
859 try
860 {
861 connection = getConnection();
862 statement = connection.prepareStatement(__selectSession);
863 statement.setString(1, id);
864 statement.setString(2, canonicalContextPath);
865 statement.setString(3, vhost);
866 ResultSet result = statement.executeQuery();
867 if (result.next())
868 {
869 data = new SessionData(id);
870 data.setRowId(result.getString(__sessionTableRowId));
871 data.setCookieSet(result.getLong("cookieTime"));
872 data.setLastAccessed(result.getLong("lastAccessTime"));
873 data.setAccessed (result.getLong("accessTime"));
874 data.setCreated(result.getLong("createTime"));
875 data.setLastNode(result.getString("lastNode"));
876 data.setLastSaved(result.getLong("lastSavedTime"));
877 data.setExpiryTime(result.getLong("expiryTime"));
878 data.setCanonicalContext(result.getString("contextPath"));
879 data.setVirtualHost(result.getString("virtualHost"));
880
881 InputStream is = ((JDBCSessionIdManager)getSessionIdManager())._dbAdaptor.getBlobInputStream(result, "map");
882 ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream (is);
883 Object o = ois.readObject();
884 data.setAttributeMap((Map<String,Object>)o);
885 ois.close();
886
887 if (Log.isDebugEnabled())
888 Log.debug("LOADED session "+data);
889 }
890 _reference.set(data);
891 }
892 catch (Exception e)
893 {
894 _exception.set(e);
895 }
896 finally
897 {
898 if (connection!=null)
899 {
900 try { connection.close();}
901 catch(Exception e) { Log.warn(e); }
902 }
903 }
904 }
905 };
906
907 if (_context==null)
908 load.run();
909 else
910 _context.getContextHandler().handle(load);
911
912 if (_exception.get()!=null)
913 throw _exception.get();
914
915 return _reference.get();
916 }
917
918
919
920
921
922
923
924 protected void storeSession (SessionData data)
925 throws Exception
926 {
927 if (data==null)
928 return;
929
930
931 Connection connection = getConnection();
932 PreparedStatement statement = null;
933 try
934 {
935 String rowId = calculateRowId(data);
936
937 long now = System.currentTimeMillis();
938 connection.setAutoCommit(true);
939 statement = connection.prepareStatement(__insertSession);
940 statement.setString(1, rowId);
941 statement.setString(2, data.getId());
942 statement.setString(3, data.getCanonicalContext());
943 statement.setString(4, data.getVirtualHost());
944 statement.setString(5, getSessionIdManager().getWorkerName());
945 statement.setLong(6, data.getAccessed());
946 statement.setLong(7, data.getLastAccessed());
947 statement.setLong(8, data.getCreated());
948 statement.setLong(9, data.getCookieSet());
949 statement.setLong(10, now);
950 statement.setLong(11, data.getExpiryTime());
951
952 ByteArrayOutputStream baos = new ByteArrayOutputStream();
953 ObjectOutputStream oos = new ObjectOutputStream(baos);
954 oos.writeObject(data.getAttributeMap());
955 byte[] bytes = baos.toByteArray();
956
957 ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
958 statement.setBinaryStream(12, bais, bytes.length);
959
960 statement.executeUpdate();
961 data.setRowId(rowId);
962 data.setLastSaved(now);
963
964
965 if (Log.isDebugEnabled())
966 Log.debug("Stored session "+data);
967 }
968 finally
969 {
970 if (connection!=null)
971 connection.close();
972 }
973 }
974
975
976
977
978
979
980
981
982 protected void updateSession (SessionData data)
983 throws Exception
984 {
985 if (data==null)
986 return;
987
988 Connection connection = getConnection();
989 PreparedStatement statement = null;
990 try
991 {
992 long now = System.currentTimeMillis();
993 connection.setAutoCommit(true);
994 statement = connection.prepareStatement(__updateSession);
995 statement.setString(1, getSessionIdManager().getWorkerName());
996 statement.setLong(2, data.getAccessed());
997 statement.setLong(3, data.getLastAccessed());
998 statement.setLong(4, now);
999 statement.setLong(5, data.getExpiryTime());
1000
1001 ByteArrayOutputStream baos = new ByteArrayOutputStream();
1002 ObjectOutputStream oos = new ObjectOutputStream(baos);
1003 oos.writeObject(data.getAttributeMap());
1004 byte[] bytes = baos.toByteArray();
1005 ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
1006
1007 statement.setBinaryStream(6, bais, bytes.length);
1008 statement.setString(7, data.getRowId());
1009 statement.executeUpdate();
1010
1011 data.setLastSaved(now);
1012 if (Log.isDebugEnabled())
1013 Log.debug("Updated session "+data);
1014 }
1015 finally
1016 {
1017 if (connection!=null)
1018 connection.close();
1019 }
1020 }
1021
1022
1023
1024
1025
1026
1027
1028
1029 protected void updateSessionNode (SessionData data)
1030 throws Exception
1031 {
1032 String nodeId = getSessionIdManager().getWorkerName();
1033 Connection connection = getConnection();
1034 PreparedStatement statement = null;
1035 try
1036 {
1037 connection.setAutoCommit(true);
1038 statement = connection.prepareStatement(__updateSessionNode);
1039 statement.setString(1, nodeId);
1040 statement.setString(2, data.getRowId());
1041 statement.executeUpdate();
1042 statement.close();
1043 if (Log.isDebugEnabled())
1044 Log.debug("Updated last node for session id="+data.getId()+", lastNode = "+nodeId);
1045 }
1046 finally
1047 {
1048 if (connection!=null)
1049 connection.close();
1050 }
1051 }
1052
1053
1054
1055
1056
1057
1058
1059 private void updateSessionAccessTime (SessionData data)
1060 throws Exception
1061 {
1062 Connection connection = getConnection();
1063 PreparedStatement statement = null;
1064 try
1065 {
1066 long now = System.currentTimeMillis();
1067 connection.setAutoCommit(true);
1068 statement = connection.prepareStatement(__updateSessionAccessTime);
1069 statement.setString(1, getSessionIdManager().getWorkerName());
1070 statement.setLong(2, data.getAccessed());
1071 statement.setLong(3, data.getLastAccessed());
1072 statement.setLong(4, now);
1073 statement.setLong(5, data.getExpiryTime());
1074 statement.setString(6, data.getRowId());
1075 statement.executeUpdate();
1076 data.setLastSaved(now);
1077 statement.close();
1078 if (Log.isDebugEnabled())
1079 Log.debug("Updated access time session id="+data.getId());
1080 }
1081 finally
1082 {
1083 if (connection!=null)
1084 connection.close();
1085 }
1086 }
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098 protected void deleteSession (SessionData data)
1099 throws Exception
1100 {
1101 Connection connection = getConnection();
1102 PreparedStatement statement = null;
1103 try
1104 {
1105 connection.setAutoCommit(true);
1106 statement = connection.prepareStatement(__deleteSession);
1107 statement.setString(1, data.getRowId());
1108 statement.executeUpdate();
1109 if (Log.isDebugEnabled())
1110 Log.debug("Deleted Session "+data);
1111 }
1112 finally
1113 {
1114 if (connection!=null)
1115 connection.close();
1116 }
1117 }
1118
1119
1120
1121
1122
1123
1124
1125
1126 private Connection getConnection ()
1127 throws SQLException
1128 {
1129 return ((JDBCSessionIdManager)getSessionIdManager()).getConnection();
1130 }
1131
1132
1133
1134
1135
1136
1137
1138
1139 private String calculateRowId (SessionData data)
1140 {
1141 String rowId = canonicalize(_context.getContextPath());
1142 rowId = rowId + "_" + getVirtualHost(_context);
1143 rowId = rowId+"_"+data.getId();
1144 return rowId;
1145 }
1146
1147
1148
1149
1150
1151
1152
1153
1154 private String getVirtualHost (ContextHandler.Context context)
1155 {
1156 String vhost = "0.0.0.0";
1157
1158 if (context==null)
1159 return vhost;
1160
1161 String [] vhosts = context.getContextHandler().getVirtualHosts();
1162 if (vhosts==null || vhosts.length==0 || vhosts[0]==null)
1163 return vhost;
1164
1165 return vhosts[0];
1166 }
1167
1168
1169
1170
1171
1172
1173
1174 private String canonicalize (String path)
1175 {
1176 if (path==null)
1177 return "";
1178
1179 return path.replace('/', '_').replace('.','_').replace('\\','_');
1180 }
1181 }