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.processing;
20  
21  import java.time.Instant;
22  import java.util.ArrayList;
23  import java.util.Collections;
24  import java.util.HashMap;
25  import java.util.List;
26  import java.util.Map;
27  
28  import org.apache.logging.log4j.LogManager;
29  import org.mycore.common.MCRSessionMgr;
30  
31  /**
32   * Can be used as base class for an {@link MCRProcessable}. This class offers some
33   * convenient methods but does not handle everything.
34   * 
35   * <p>
36   * If you extend this class make sure to call {@link #setStatus(MCRProcessableStatus)},
37   * {@link #setProgress(Integer)} and {@link #setProgressText(String)}. Otherwise the
38   * event handlers are not fired.
39   * </p>
40   * 
41   * @author Matthias Eichner
42   */
43  public class MCRAbstractProcessable extends MCRAbstractProgressable implements MCRProcessable {
44  
45      protected String name;
46  
47      protected String userId;
48  
49      protected MCRProcessableStatus status;
50  
51      protected Throwable error;
52  
53      protected Instant createTime;
54  
55      protected Instant startTime;
56  
57      protected Instant endTime;
58  
59      protected Map<String, Object> properties;
60  
61      protected final List<MCRProcessableStatusListener> statusListener;
62  
63      public MCRAbstractProcessable() {
64          super();
65          this.name = null;
66          if (MCRSessionMgr.hasCurrentSession()) {
67              // do not create a new session! (getCurrentSession() is wrong named!)
68              this.userId = MCRSessionMgr.getCurrentSession().getUserInformation().getUserID();
69          }
70          this.status = MCRProcessableStatus.created;
71          this.error = null;
72  
73          this.createTime = Instant.now();
74          this.startTime = null;
75          this.endTime = null;
76  
77          this.properties = new HashMap<>();
78  
79          this.statusListener = Collections.synchronizedList(new ArrayList<>());
80      }
81  
82      /**
83       * Sets the name for this process.
84       * 
85       * @param name human readable name
86       */
87      public void setName(String name) {
88          this.name = name;
89      }
90  
91      @Override
92      public String getName() {
93          return this.name;
94      }
95  
96      /**
97       * Sets the user identifier responsible for this processable.
98       * 
99       * @param userId the user id
100      */
101     public void setUserId(String userId) {
102         this.userId = userId;
103     }
104 
105     @Override
106     public String getUserId() {
107         return this.userId;
108     }
109 
110     @Override
111     public Throwable getError() {
112         return this.error;
113     }
114 
115     /**
116      * Sets the internal processable error. This will set the status to failed.
117      * 
118      * @param error the error
119      */
120     public void setError(Throwable error) {
121         this.error = error;
122         setStatus(MCRProcessableStatus.failed);
123     }
124 
125     /**
126      * Sets the new status. If the status is equal "processing" the startTime is set, if the status is equal
127      * "successful", "failed" or "canceled" the endTime is set. This will call the fireStatusChanged method.
128      * 
129      * @param status the new status
130      */
131     public void setStatus(MCRProcessableStatus status) {
132         MCRProcessableStatus oldStatus = this.status;
133         this.status = status;
134         if (status.equals(MCRProcessableStatus.processing)) {
135             this.startTime = Instant.now();
136         }
137         if (status.equals(MCRProcessableStatus.successful) || status.equals(MCRProcessableStatus.failed) ||
138             status.equals(MCRProcessableStatus.canceled)) {
139             this.endTime = Instant.now();
140         }
141         fireStatusChanged(oldStatus);
142     }
143 
144     @Override
145     public MCRProcessableStatus getStatus() {
146         return this.status;
147     }
148 
149     @Override
150     public Instant getStartTime() {
151         return this.startTime;
152     }
153 
154     @Override
155     public Instant getCreateTime() {
156         return this.createTime;
157     }
158 
159     @Override
160     public Instant getEndTime() {
161         return this.endTime;
162     }
163 
164     @Override
165     public Map<String, Object> getProperties() {
166         return this.properties;
167     }
168 
169     @Override
170     public void addStatusListener(MCRProcessableStatusListener listener) {
171         this.statusListener.add(listener);
172     }
173 
174     @Override
175     public void removeStatusListener(MCRProcessableStatusListener listener) {
176         this.statusListener.remove(listener);
177     }
178 
179     protected void fireStatusChanged(MCRProcessableStatus oldStatus) {
180         synchronized (this.statusListener) {
181             this.statusListener.forEach(listener -> {
182                 try {
183                     listener.onStatusChange(this, oldStatus, getStatus());
184                 } catch (Exception exc) {
185                     LogManager.getLogger().error("Unable to execute onStatusChange() on listener '{}' for '{}'",
186                         listener.getClass().getName(), getName(), exc);
187                 }
188             });
189         }
190     }
191 
192 }