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