1. Project Clover database Sat Feb 2 2019 06:45:20 CET
  2. Package org.xwiki.job.internal

File DefaultJobProgress.java

 

Coverage histogram

../../../../img/srcFileCovDistChart10.png
0% of files have more coverage

Code metrics

40
62
16
1
265
157
39
0.63
3.88
16
2.44

Classes

Class Line # Actions
DefaultJobProgress 41 62 0% 39 10
0.9152542491.5%
 

Contributing tests

This file is covered by 231 tests. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software 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 GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.job.internal;
21   
22    import java.util.Arrays;
23    import java.util.List;
24   
25    import org.slf4j.Logger;
26    import org.slf4j.LoggerFactory;
27    import org.xwiki.job.event.status.EndStepProgressEvent;
28    import org.xwiki.job.event.status.JobProgress;
29    import org.xwiki.job.event.status.PopLevelProgressEvent;
30    import org.xwiki.job.event.status.PushLevelProgressEvent;
31    import org.xwiki.job.event.status.StartStepProgressEvent;
32    import org.xwiki.job.event.status.StepProgressEvent;
33    import org.xwiki.logging.Message;
34    import org.xwiki.observation.EventListener;
35    import org.xwiki.observation.event.Event;
36   
37    /**
38    * @version $Id: f38e8a4c89d04b615810968a3aeaa603e65ac06b $
39    * @since 4.0M1
40    */
 
41    public class DefaultJobProgress implements EventListener, JobProgress
42    {
43    /**
44    * The object used to log messages.
45    */
46    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultJobProgress.class);
47   
48    /**
49    * Listened events.
50    */
51    private static final List<Event> EVENTS =
52    Arrays.<Event>asList(new PushLevelProgressEvent(), PopLevelProgressEvent.INSTANCE, StepProgressEvent.INSTANCE,
53    StartStepProgressEvent.INSTANCE, EndStepProgressEvent.INSTANCE);
54   
55    private final String listenerName;
56   
57    private final DefaultJobProgressStep rootStep;
58   
59    private transient DefaultJobProgressStep currentStep;
60   
61    /**
62    * Default constructor.
63    */
 
64  220681 toggle public DefaultJobProgress()
65    {
66  220682 this(null);
67    }
68   
69    /**
70    * @param name the name associated to the job progress
71    */
 
72  220679 toggle public DefaultJobProgress(String name)
73    {
74  220681 this.listenerName = name != null ? name : getClass().getName() + '_' + System.identityHashCode(this);
75   
76  220681 this.rootStep =
77    new DefaultJobProgressStep(new Message("job.progress", "Progress with name [{}]", name), null, null);
78  220682 this.currentStep = this.rootStep;
79    }
80   
81    // EventListener
82   
 
83  230284 toggle @Override
84    public String getName()
85    {
86  230279 return this.listenerName;
87    }
88   
 
89  21928 toggle @Override
90    public List<Event> getEvents()
91    {
92  21928 return EVENTS;
93    }
94   
 
95  325559 toggle @Override
96    public void onEvent(Event event, Object source, Object message)
97    {
98  326178 if (event instanceof PushLevelProgressEvent) {
99  5303 onPushLevelProgress(((PushLevelProgressEvent) event).getSteps(), source, false);
100  320836 } else if (event instanceof PopLevelProgressEvent) {
101  5294 onPopLevelProgress(source);
102  315177 } else if (event instanceof StartStepProgressEvent) {
103  159387 onStartStepProgress((Message) message, source);
104  156329 } else if (event instanceof EndStepProgressEvent) {
105  156368 onEndStepProgress(source);
106  5 } else if (event instanceof StepProgressEvent) {
107  5 onStepProgress(source);
108    }
109    }
110   
111    /**
112    * Adds a new level to the progress stack.
113    */
 
114  79693 toggle private void onPushLevelProgress(int steps, Object source, boolean singlesteplevel)
115    {
116  79263 if (this.currentStep.isLevelFinished()) {
117    // If current step is done move to next one
118  160 this.currentStep = this.currentStep.getParent().nextStep(null, source);
119    }
120   
121    // Add level
122  79060 this.currentStep = this.currentStep.addLevel(steps, source, singlesteplevel);
123    }
124   
125    /**
126    * Close current step.
127    */
 
128  156322 toggle private void onEndStepProgress(Object source)
129    {
130    // Try to find the right step based on the source
131  156376 DefaultJobProgressStep step = findStep(this.currentStep, source);
132   
133  156285 if (step == null) {
134  0 LOGGER.warn("Could not find any matching step for source [{}]. Ignoring EndStepProgress.",
135    source.toString());
136   
137  0 return;
138    }
139   
140  156309 this.currentStep = step;
141  156318 this.currentStep.finish();
142    }
143   
 
144  157733 toggle private void onStartStepProgress(Message message, Object source)
145    {
146  158881 if (this.currentStep.getParent() == null) {
147    // If we are still on root node, create a level
148  21131 this.currentStep = this.currentStep.addLevel(source);
149  137988 } else if (!this.currentStep.isFinished() && this.currentStep.source != source) {
150    // If current step is from a different source add a level
151  74731 onPushLevelProgress(0, source, true);
152  63274 } else if (this.currentStep.getParent().levelStep && this.currentStep.getParent().source == source) {
153    // If current step is not part of an explicit level and parent level is asked, go back to it
154  3 this.currentStep = this.currentStep.getParent();
155  3 this.currentStep.finishLevel();
156    }
157   
158    // Start a new step
159  157788 this.currentStep = this.currentStep.getParent().nextStep(message, source);
160    }
161   
162    /**
163    * Move progress to next step.
164    *
165    * @deprecated since 7.1M2, use {@link #onStartStepProgress(Message)} instead
166    */
 
167  5 toggle @Deprecated
168    private void onStepProgress(Object source)
169    {
170  5 onStartStepProgress(null, source);
171   
172    // if there is only one step close it and move to the next one
173  5 if (this.currentStep.getParent().getChildren().size() == 1) {
174  3 this.currentStep = this.currentStep.getParent().nextStep(null, source);
175    }
176    }
177   
178    /**
179    * Called when a {@link PopLevelProgressEvent} is fired.
180    */
 
181  5294 toggle private void onPopLevelProgress(Object source)
182    {
183  5294 DefaultJobProgressStep parent = this.currentStep.getParent();
184   
185  5294 if (parent == null) {
186  0 LOGGER.warn("PopLevelProgressEvent was fired too many times. Don't forget "
187    + "to match each PopLevelProgressEvent with a PushLevelProgressEvent.");
188   
189  0 return;
190    }
191   
192    // Try to find the right level based on the source
193  5294 DefaultJobProgressStep level = findLevel(this.currentStep.getParent(), source);
194   
195  5294 if (level == null) {
196  1 LOGGER.warn("Could not find any matching step level for source [{}]. Ignoring PopLevelProgressEvent.",
197    source.toString());
198   
199  1 return;
200    }
201   
202    // Move to parent step
203  5293 this.currentStep = level;
204   
205    // Close the level
206  5293 this.currentStep.finishLevel();
207    }
208   
 
209  156255 toggle private DefaultJobProgressStep findStep(DefaultJobProgressStep step, Object source)
210    {
211  156341 DefaultJobProgressStep matchingStep = step;
212   
213  156351 do {
214  231256 if (matchingStep.source == source) {
215  156327 return matchingStep;
216    }
217   
218  74908 matchingStep = matchingStep.getParent();
219  74915 } while (matchingStep != null);
220   
221  0 return null;
222    }
223   
 
224  5294 toggle private DefaultJobProgressStep findLevel(DefaultJobProgressStep step, Object levelSource)
225    {
226  5294 DefaultJobProgressStep matchingStep = step;
227   
228  5294 do {
229  5425 if (levelSource == null || matchingStep.levelSource == levelSource) {
230  5293 return matchingStep;
231    }
232   
233  132 matchingStep = matchingStep.getParent();
234  132 } while (matchingStep != null);
235   
236  1 return null;
237    }
238   
239    // JobProgress
240   
 
241  459 toggle @Override
242    public double getOffset()
243    {
244  459 return this.rootStep.getOffset();
245    }
246   
 
247  101 toggle @Override
248    public double getCurrentLevelOffset()
249    {
250  101 return getCurrentStep().getParent() != null ? getCurrentStep().getParent().getOffset() : getOffset();
251    }
252   
 
253  21999 toggle @Override
254    public DefaultJobProgressStep getRootStep()
255    {
256  21999 return this.rootStep;
257    }
258   
 
259  131 toggle @Override
260    public DefaultJobProgressStep getCurrentStep()
261    {
262    // currentStep could be null for unserialized job progress
263  131 return this.currentStep != null ? this.currentStep : this.rootStep;
264    }
265    }