1
+ /*
2
+ * Copyright (C) 2000 - 2025 Silverpeas
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify
5
+ * it under the terms of the GNU Affero General Public License as
6
+ * published by the Free Software Foundation, either version 3 of the
7
+ * License, or (at your option) any later version.
8
+ *
9
+ * As a special exception to the terms and conditions of version 3.0 of
10
+ * the GPL, you may redistribute this Program in connection with Free/Libre
11
+ * Open Source Software ("FLOSS") applications as described in Silverpeas's
12
+ * FLOSS exception. You should have received a copy of the text describing
13
+ * the FLOSS exception, and it is also available here:
14
+ * "https://www.silverpeas.org/legal/floss_exception.html"
15
+ *
16
+ * This program is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
+ * GNU Affero General Public License for more details.
20
+ *
21
+ * You should have received a copy of the GNU Affero General Public License
22
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
23
+ */
24
+
25
+ package org .silverpeas .components .kmelia .service ;
26
+
27
+ import org .silverpeas .core .admin .component .model .WAComponent ;
28
+ import org .silverpeas .core .annotation .Service ;
29
+ import org .silverpeas .core .contribution .model .Contribution ;
30
+ import org .silverpeas .core .contribution .publication .service .PublicationService ;
31
+ import org .silverpeas .core .initialization .Initialization ;
32
+ import org .silverpeas .core .node .model .NodePK ;
33
+ import org .silverpeas .core .node .service .NodeService ;
34
+ import org .silverpeas .core .scheduler .Job ;
35
+ import org .silverpeas .core .scheduler .JobExecutionContext ;
36
+ import org .silverpeas .core .scheduler .Scheduler ;
37
+ import org .silverpeas .core .scheduler .SchedulerProvider ;
38
+ import org .silverpeas .core .scheduler .trigger .JobTrigger ;
39
+ import org .silverpeas .kernel .SilverpeasRuntimeException ;
40
+ import org .silverpeas .kernel .bundle .ResourceLocator ;
41
+ import org .silverpeas .kernel .bundle .SettingBundle ;
42
+ import org .silverpeas .kernel .logging .SilverLogger ;
43
+
44
+ import javax .inject .Inject ;
45
+ import javax .transaction .Transactional ;
46
+ import java .time .LocalDate ;
47
+ import java .util .Date ;
48
+
49
+ import static org .silverpeas .core .util .DateUtil .toLocalDate ;
50
+
51
+ /**
52
+ * A service scheduled in time to clean out periodically the bin in each Kmelia instances of the
53
+ * items (both topics and publications) that have been removed since a given number of days. The
54
+ * purge scheduling and the delay in days can be parameterized in the
55
+ * <code>org/silverpeas/kmelia/settings/kmeliaSettings.properties</code> configuration file.
56
+ *
57
+ * @author mmoquillon
58
+ */
59
+ @ Service
60
+ public class KmeliaBinsScheduledPurger implements Initialization {
61
+
62
+ private static final String COMPONENT_NAME = "kmelia" ;
63
+ private static final String SETTINGS_NAME = "org.silverpeas.kmelia.settings.kmeliaSettings" ;
64
+ private static final String JOB_NAME = "OldBinItemsDeleter" ;
65
+
66
+ @ Inject
67
+ private KmeliaDeleter deleter ;
68
+ @ Inject
69
+ private NodeService nodeService ;
70
+ @ Inject
71
+ private PublicationService publicationService ;
72
+
73
+ @ Override
74
+ public void init () throws Exception {
75
+ String cron = getSchedulingCron ();
76
+ if (!cron .isEmpty ()) {
77
+ final Scheduler scheduler = SchedulerProvider .getVolatileScheduler ();
78
+ scheduler .unscheduleJob (JOB_NAME );
79
+ scheduler .scheduleJob (new OldBinItemsDeleter (), JobTrigger .triggerAt (cron ));
80
+ }
81
+ new OldBinItemsDeleter ().execute (JobExecutionContext .createWith (JOB_NAME , new Date ()));
82
+ }
83
+
84
+ @ Override
85
+ public void release () throws Exception {
86
+ Scheduler scheduler = SchedulerProvider .getVolatileScheduler ();
87
+ if (scheduler .isJobScheduled (JOB_NAME )) {
88
+ scheduler .unscheduleJob (JOB_NAME );
89
+ }
90
+ }
91
+
92
+ private String getSchedulingCron () {
93
+ SettingBundle settings = ResourceLocator .getSettingBundle (SETTINGS_NAME );
94
+ return settings .getString ("kmelia.autoDeletionCron" , "" );
95
+ }
96
+
97
+ private class OldBinItemsDeleter extends Job {
98
+
99
+ OldBinItemsDeleter () {
100
+ super (JOB_NAME );
101
+ }
102
+
103
+ @ Transactional
104
+ @ Override
105
+ public void execute (final JobExecutionContext context ) {
106
+ int delay = getDeletionDelay ();
107
+ if (delay > 0 ) {
108
+ try {
109
+ final LocalDate now = LocalDate .now ();
110
+ WAComponent .getByName (COMPONENT_NAME )
111
+ .ifPresent (component ->
112
+ component .getAllInstanceIds ()
113
+ .forEach (instanceId -> {
114
+ NodePK bin = new NodePK (NodePK .BIN_NODE_ID , instanceId );
115
+ nodeService .getChildrenDetails (bin ).stream ()
116
+ .filter (node -> isOlder (node , now ))
117
+ .forEach (topic ->
118
+ deleter .deleteTopic (topic .getNodePK ()));
119
+ publicationService .getDetailsByFatherPK (bin ).stream ()
120
+ .filter (publication -> isOlder (publication , now ))
121
+ .forEach (publication ->
122
+ deleter .deletePublication (publication .getPK ()));
123
+ }));
124
+
125
+ } catch (SilverpeasRuntimeException e ) {
126
+ SilverLogger .getLogger (this ).error (e .getMessage (), e );
127
+ }
128
+ }
129
+ }
130
+
131
+ private int getDeletionDelay () {
132
+ SettingBundle settings = ResourceLocator .getSettingBundle (SETTINGS_NAME );
133
+ int delay = settings .getInteger ("kmelia.autoDeletionDelay" , 0 );
134
+ return Math .max (delay , 0 );
135
+ }
136
+
137
+ private boolean isOlder (Contribution contribution , LocalDate date ) {
138
+ final LocalDate removeDayDateWithDelay = toLocalDate (contribution .getLastUpdateDate ())
139
+ .plusDays (getDeletionDelay ());
140
+ return removeDayDateWithDelay .isBefore (date ) ||
141
+ removeDayDateWithDelay .isEqual (date );
142
+ }
143
+ }
144
+ }
145
+
0 commit comments