1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.module.rssaggregator.app.subapps.aggregationconfig;
35
36 import info.magnolia.cms.security.AccessManager;
37 import info.magnolia.cms.security.Permission;
38 import info.magnolia.context.MgnlContext;
39 import info.magnolia.i18nsystem.SimpleTranslator;
40 import info.magnolia.jcr.util.NodeUtil;
41 import info.magnolia.jcr.util.NodeVisitor;
42 import info.magnolia.jcr.util.PropertyUtil;
43 import info.magnolia.module.data.commands.ImportCommand;
44 import info.magnolia.module.rssaggregator.RSSAggregatorConstants;
45 import info.magnolia.module.rssaggregator.RSSAggregatorNodeTypes;
46 import info.magnolia.module.rssaggregator.app.subapps.aggregationconfig.view.RSSAggregatorConfigurationView;
47 import info.magnolia.module.rssaggregator.generator.CollectStatisticsCommand;
48 import info.magnolia.module.rssaggregator.generator.PlanetDataGenerator;
49 import info.magnolia.repository.RepositoryConstants;
50 import info.magnolia.ui.api.app.AppContext;
51 import info.magnolia.ui.api.context.UiContext;
52 import info.magnolia.ui.api.view.View;
53 import info.magnolia.ui.vaadin.overlay.MessageStyleTypeEnum;
54
55 import javax.inject.Inject;
56 import javax.jcr.Node;
57 import javax.jcr.RepositoryException;
58 import javax.jcr.Session;
59
60 import org.apache.jackrabbit.commons.predicate.IsNodePredicate;
61 import org.slf4j.Logger;
62 import org.slf4j.LoggerFactory;
63
64
65
66
67
68
69 public class RSSAggregatorConfigurationPresenter implements RSSAggregatorConfigurationView.Listener {
70
71 private static final String IMPORT_ERROR_LABEL = "rssAggregator.config.notification.import_error";
72
73 private static final String TASKS = "/modules/data/config/importers/rssaggregator/automatedExecution";
74
75 private static final String PLANET_DATA_PATH = "/modules/scheduler/config/jobs/generatePlanetData";
76
77 private static final String PLANET_STATISTICS_PATH = "/modules/scheduler/config/jobs/collectPlanetStatistics";
78
79 private static final String IMPORT_COMPLETE_LABEL = "rssAggregator.config.notification.import_complete";
80
81 private static final String SETTINGS_CHANGED_LABEL = "rssAggregator.config.notification.settings_changed";
82
83 public static final String PLANET_DATA_CHANGED_LABEL = "rssAggregator.config.notification.planet_data_changed";
84
85 public static final String STATISTICS_COLLECTED_LABEL = "rssAggregator.config.notification.stats_collected";
86
87 private Logger log = LoggerFactory.getLogger(getClass());
88
89 private RSSAggregatorConfigurationView view;
90
91 private UiContext uiContext;
92
93 private SimpleTranslator translator;
94
95 @Inject
96 public RSSAggregatorConfigurationPresenter(RSSAggregatorConfigurationView view, AppContext uiContext, SimpleTranslator translator) {
97 this.view = view;
98 this.uiContext = uiContext;
99 this.translator = translator;
100 }
101
102 public View start() {
103 view.setListener(this);
104 return view;
105 }
106
107 protected boolean checkPermissions(String repository, String basePath, long permissionType) {
108 AccessManager accessManager = MgnlContext.getAccessManager(repository);
109 if (accessManager != null) {
110 if (!accessManager.isGranted(basePath, permissionType)) {
111 return false;
112 }
113 }
114 return true;
115 }
116
117 @Override
118 public void onManualImport() {
119 if (!checkPermissions(RSSAggregatorConstants.WORKSPACE, "/", Permission.WRITE)) {
120 uiContext.openNotification(MessageStyleTypeEnum.ERROR, false, translator.translate(IMPORT_ERROR_LABEL));
121 } else {
122 ImportCommand cmd = new ImportCommand();
123 cmd.setImporter("rssaggregator");
124 cmd.execute(MgnlContext.getInstance());
125 uiContext.openNotification(MessageStyleTypeEnum.INFO, true, translator.translate(IMPORT_COMPLETE_LABEL));
126 }
127 }
128
129 @Override
130 public void onAutomaticImportChanged(int periodMinutes) {
131 try {
132 Session session = MgnlContext.getJCRSession("config");
133 Node execution = session.getNode(TASKS);
134 execution.setProperty("enabled", true);
135 execution.setProperty("cron", "0 0/" + periodMinutes + " * * * *");
136 session.save();
137 uiContext.openNotification(MessageStyleTypeEnum.INFO, true, translator.translate(SETTINGS_CHANGED_LABEL));
138 } catch (RepositoryException e) {
139 displayException(e, "Failed to update automatic update period");
140 }
141
142 }
143
144 @Override
145 public void onAutomaticPlanetUpdateChanged(int value) {
146 try {
147 Session session = MgnlContext.getJCRSession("config");
148 Node planetDataScheduler = session.getNode(PLANET_DATA_PATH);
149 PropertyUtil.setProperty(planetDataScheduler, "active", true);
150 PropertyUtil.setProperty(planetDataScheduler, "cron", "0 0/" + value + " * * * *");
151 session.save();
152 uiContext.openNotification(MessageStyleTypeEnum.INFO, true, SETTINGS_CHANGED_LABEL);
153 } catch (RepositoryException e) {
154 displayException(e, "Failed to change planet update period: ");
155 }
156 }
157
158 @Override
159 public void onPlanetDataManualUpdate() {
160 try {
161 PlanetDataGenerator pdg = new PlanetDataGenerator();
162 pdg.execute(MgnlContext.getInstance());
163 uiContext.openNotification(MessageStyleTypeEnum.INFO, true, translator.translate(PLANET_DATA_CHANGED_LABEL));
164 } catch (Exception e) {
165 displayException(e, "Failed to update planet data: ");
166 }
167
168 }
169
170 @Override
171 public void onPlanetStatisticsManualUpdate() {
172 CollectStatisticsCommand csc = new CollectStatisticsCommand();
173 try {
174 csc.execute(MgnlContext.getInstance());
175 uiContext.openNotification(MessageStyleTypeEnum.INFO, true, translator.translate(STATISTICS_COLLECTED_LABEL));
176 } catch (Exception e) {
177 displayException(e, "Failed to collect statistics: ");
178 }
179 }
180
181 @Override
182 public void onPlanetStatisticsAutomaticUpdatePeriodChanged(int value) {
183 try {
184 Session session = MgnlContext.getJCRSession("config");
185 Node planetStatisticsScheduler = session.getNode(PLANET_STATISTICS_PATH);
186 PropertyUtil.setProperty(planetStatisticsScheduler, "active", true);
187 PropertyUtil.setProperty(planetStatisticsScheduler, "cron", "0 0/" + value + " * * * *");
188 session.save();
189 uiContext.openNotification(MessageStyleTypeEnum.INFO, true, translator.translate(SETTINGS_CHANGED_LABEL));
190 } catch (RepositoryException e) {
191 displayException(e, "Failed to update planet update period: ");
192 }
193
194 }
195
196 private void displayException(Exception e, String msg) {
197 uiContext.openNotification(MessageStyleTypeEnum.ERROR, false, msg + e.getMessage());
198 log.error(msg, e);
199 }
200
201 public void updateConfiguration() {
202 view.setDataImportPeriod(parseAutoUpdatePeriod(TASKS));
203 view.setPlanetStatsImportPeriod(parseAutoUpdatePeriod(PLANET_STATISTICS_PATH));
204 view.setPlanetDataImportPeriod(parseAutoUpdatePeriod(PLANET_DATA_PATH));
205
206 boolean isPlanetVisible = false;
207 try {
208 Node root = MgnlContext.getJCRSession(RSSAggregatorConstants.WORKSPACE).getRootNode();
209 PlanetFeedSearcher searcher = new PlanetFeedSearcher();
210 NodeUtil.visit(root, searcher, new IsNodePredicate());
211 isPlanetVisible = searcher.isPlanetFeedFound();
212 } catch (RepositoryException e) {
213 log.warn("Problem occurred while checking planet config visibility ", e);
214 }
215
216 view.setPlanetConfigVisible(isPlanetVisible);
217 }
218
219 private int parseAutoUpdatePeriod(String path) {
220 try {
221 Session session = MgnlContext.getJCRSession(RepositoryConstants.CONFIG);
222 Node execution = session.getNode(path);
223 String[] cron = execution.getProperty("cron").getString().split(" ");
224 if (cron[1].indexOf('/') < 0) {
225 return 0;
226 } else {
227 return Integer.parseInt(cron[1].substring(cron[1].indexOf('/') + 1));
228 }
229 } catch (RepositoryException e) {
230 return 0;
231 }
232 }
233
234 private static class PlanetFeedSearcher implements NodeVisitor {
235
236 private boolean isPlanetFeedFound = false;
237
238 @Override
239 public void visit(Node node) throws RepositoryException {
240 isPlanetFeedFound = isPlanetFeedFound ||
241 (NodeUtil.isNodeType(node, RSSAggregatorNodeTypes.RSSAggregator.NAME) &&
242 PropertyUtil.getBoolean(node, "planetFeed", false));
243 }
244
245 public boolean isPlanetFeedFound() {
246 return isPlanetFeedFound;
247 }
248 }
249 }