View Javadoc
1   /*
2    * This file is part of ***  M y C o R e  ***
3    * See http://www.mycore.de/ for details.
4    *
5    * MyCoRe is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    *
10   * MyCoRe is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with MyCoRe.  If not, see <http://www.gnu.org/licenses/>.
17   */
18  
19  package org.mycore.common;
20  
21  import java.io.Serializable;
22  import java.util.Objects;
23  import java.util.Optional;
24  
25  import org.apache.logging.log4j.LogManager;
26  import org.apache.logging.log4j.Logger;
27  import org.mycore.frontend.servlets.MCRServlet;
28  
29  import jakarta.servlet.http.HttpSessionBindingEvent;
30  import jakarta.servlet.http.HttpSessionBindingListener;
31  
32  /**
33   * This Class will be stored in the a {@link jakarta.servlet.http.HttpSession} and can be used to resolve the
34   * {@link MCRSession}. We can not store {@link MCRSession} directly in the {@link jakarta.servlet.http.HttpSession}
35   * because values need to be {@link java.io.Serializable}.
36   */
37  public final class MCRSessionResolver implements Serializable, HttpSessionBindingListener {
38  
39      private static final Logger LOGGER = LogManager.getLogger();
40  
41      private final String sessionID;
42  
43      private MCRSessionResolver(final String sessionID) {
44          this.sessionID = sessionID;
45      }
46  
47      public MCRSessionResolver(final MCRSession session) {
48          this(session.getID());
49      }
50  
51      public String getSessionID() {
52          return sessionID;
53      }
54  
55      /**
56       * Tries to resolve the {@link MCRSession} throught the {@link MCRSessionMgr}
57       *
58       * @return if is already closed it will return a {@link Optional#empty()}
59       */
60      public Optional<MCRSession> resolveSession() {
61          return Optional.ofNullable(MCRSessionMgr.getSession(sessionID));
62      }
63  
64      @Override
65      public void valueBound(HttpSessionBindingEvent hsbe) {
66          Object obj = hsbe.getValue();
67          if (LOGGER.isDebugEnabled() && obj instanceof MCRSessionResolver) {
68              LOGGER.debug("Bound MCRSession {} to HttpSession {}", ((MCRSessionResolver) obj).getSessionID(),
69                  hsbe.getSession().getId());
70          }
71      }
72  
73      @Override
74      public void valueUnbound(HttpSessionBindingEvent hsbe) {
75          // hsbe.getValue() does not work right with tomcat
76          Optional<MCRSessionResolver> newSessionResolver = Optional
77              .ofNullable(hsbe.getSession().getAttribute(MCRServlet.ATTR_MYCORE_SESSION))
78              .filter(o -> o instanceof MCRSessionResolver)
79              .map(MCRSessionResolver.class::cast);
80          MCRSessionResolver oldResolver = this;
81          if (newSessionResolver.isPresent() && !oldResolver.equals(newSessionResolver.get())) {
82              LOGGER.warn("Attribute {} is beeing unbound from session {} and replaced by {}!", hsbe.getName(),
83                  oldResolver.getSessionID(), newSessionResolver.get());
84              oldResolver.resolveSession().ifPresent(MCRSession::close);
85          }
86  
87      }
88  
89      @Override
90      public boolean equals(Object o) {
91          if (this == o) {
92              return true;
93          }
94          if (o == null || getClass() != o.getClass()) {
95              return false;
96          }
97          MCRSessionResolver that = (MCRSessionResolver) o;
98          return Objects.equals(getSessionID(), that.getSessionID());
99      }
100 
101     @Override
102     public int hashCode() {
103         return Objects.hash(getSessionID());
104     }
105 
106     @Override
107     public String toString() {
108         return "Resolver to " + getSessionID();
109     }
110 }