NewsletterManagerImpl.java
14.3 KB
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
/*
* Decompiled with CFR 0_118.
*
* Could not load the following classes:
* com.day.cq.wcm.api.Page
* javax.jcr.Node
* javax.jcr.RepositoryException
* javax.jcr.Session
* javax.jcr.Workspace
* javax.jcr.lock.Lock
* javax.jcr.lock.LockManager
* org.apache.felix.scr.annotations.Component
* org.apache.felix.scr.annotations.Reference
* org.apache.felix.scr.annotations.Service
* org.apache.sling.api.resource.ModifiableValueMap
* org.apache.sling.api.resource.PersistenceException
* org.apache.sling.api.resource.Resource
* org.apache.sling.api.resource.ResourceResolver
* org.apache.sling.api.resource.ResourceUtil
* org.apache.sling.api.resource.ValueMap
* org.slf4j.Logger
* org.slf4j.LoggerFactory
*/
package com.adobe.cq.mcm.campaign.impl;
import com.adobe.cq.mcm.campaign.NewsletterException;
import com.adobe.cq.mcm.campaign.NewsletterManager;
import com.adobe.cq.mcm.campaign.Publisher;
import com.adobe.cq.mcm.campaign.impl.Util;
import com.day.cq.wcm.api.Page;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.UUID;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Workspace;
import javax.jcr.lock.Lock;
import javax.jcr.lock.LockManager;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.resource.ModifiableValueMap;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.resource.ValueMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Component(metatype=0)
@Service
public class NewsletterManagerImpl
implements NewsletterManager {
private final Logger log;
private final String[] EMPTY_STRING_ARRAY;
@Reference
protected Publisher publisher;
public NewsletterManagerImpl() {
this.log = LoggerFactory.getLogger(this.getClass());
this.EMPTY_STRING_ARRAY = new String[0];
}
private void check(Page newsletter) throws NewsletterException {
if (!this.isNewsletter(newsletter)) {
throw new NewsletterException("Page " + newsletter.getPath() + " is not a newsletter");
}
}
@Override
public boolean isNewsletter(Page page) {
Resource content;
Resource resource = content = page != null ? page.getContentResource() : null;
if (content == null) {
return false;
}
return Util.isNewsletterType(content);
}
@Override
public boolean isLinked(Page newsletter, String deliveryId) throws NewsletterException {
this.check(newsletter);
ValueMap properties = (ValueMap)newsletter.getContentResource().adaptTo(ValueMap.class);
String[] deliveriesArray = (String[])properties.get("cq:acLinks", (Object)new String[0]);
LinkedHashSet<String> deliveriesSet = new LinkedHashSet<String>(Arrays.asList(deliveriesArray));
return deliveriesSet.contains(deliveryId);
}
@Override
public String[] getLinkedDeliveries(Page newsletter) throws NewsletterException {
this.check(newsletter);
Resource resource = newsletter.getContentResource();
ValueMap values = ResourceUtil.getValueMap((Resource)resource);
String[] links = (String[])values.get("cq:acLinks", String[].class);
if (links == null) {
links = this.EMPTY_STRING_ARRAY;
}
return links;
}
@Override
public String link(Page newsletter, String deliveryId) throws NewsletterException, PersistenceException {
String uuid;
this.check(newsletter);
Resource content = newsletter.getContentResource();
ModifiableValueMap properties = (ModifiableValueMap)content.adaptTo(ModifiableValueMap.class);
if (!this.isLinked(newsletter, deliveryId)) {
String[] deliveriesArray = (String[])properties.get("cq:acLinks", (Object)new String[0]);
LinkedHashSet<String> deliveriesSet = new LinkedHashSet<String>(Arrays.asList(deliveriesArray));
deliveriesSet.add(deliveryId);
deliveriesArray = deliveriesSet.toArray(new String[0]);
properties.put((Object)"cq:acLinks", (Object)deliveriesArray);
}
if ((uuid = (String)properties.get("cq:acUUID", (Object)null)) == null) {
uuid = UUID.randomUUID().toString();
properties.put((Object)"cq:acUUID", (Object)uuid);
}
content.getResourceResolver().commit();
return uuid;
}
@Override
public void unlink(Page newsletter, String deliveryId) throws NewsletterException, PersistenceException {
this.check(newsletter);
Resource content = newsletter.getContentResource();
if (!this.isLinked(newsletter, deliveryId)) {
return;
}
ModifiableValueMap properties = (ModifiableValueMap)content.adaptTo(ModifiableValueMap.class);
if (deliveryId.equals(properties.get("cq:acLockedBy", (Object)null))) {
throw new NewsletterException("Cannot unlink delivery that was used to lock the newsletter");
}
String[] deliveriesArray = (String[])properties.get("cq:acLinks", (Object)new String[0]);
LinkedHashSet<String> deliveriesSet = new LinkedHashSet<String>(Arrays.asList(deliveriesArray));
deliveriesSet.remove(deliveryId);
deliveriesArray = deliveriesSet.toArray(new String[0]);
if (deliveriesArray.length > 0) {
properties.put((Object)"cq:acLinks", (Object)deliveriesArray);
} else {
properties.remove((Object)"cq:acLinks");
}
content.getResourceResolver().commit();
}
@Override
public boolean isModifiedSince(Page newsletter, long timestamp) throws NewsletterException {
this.check(newsletter);
long lastModified = this.getLastModified(newsletter);
return lastModified > timestamp;
}
@Override
public long getLastModified(Page newsletter) throws NewsletterException {
this.check(newsletter);
Resource content = newsletter.getContentResource();
ValueMap properties = (ValueMap)content.adaptTo(ValueMap.class);
Date lastModified = (Date)properties.get("cq:lastModified", Date.class);
return lastModified.getTime();
}
@Override
public String getSubject(Page newsletter) throws NewsletterException {
this.check(newsletter);
Resource content = newsletter.getContentResource();
ValueMap properties = (ValueMap)content.adaptTo(ValueMap.class);
String subject = properties.containsKey((Object)"subject") ? (String)properties.get("subject", String.class) : newsletter.getTitle();
if (subject == null) {
throw new NewsletterException("No subject found (neither subject nor page title are available).");
}
return subject;
}
@Override
public String getPlainText(Page newsletter) throws NewsletterException {
this.check(newsletter);
Resource content = newsletter.getContentResource();
ValueMap properties = (ValueMap)content.adaptTo(ValueMap.class);
String plainText = null;
if (properties.containsKey((Object)"plaintext")) {
plainText = (String)properties.get("plaintext", String.class);
}
return plainText;
}
@Override
public boolean isApproved(Page newsletter) throws NewsletterException {
this.check(newsletter);
Resource content = newsletter.getContentResource();
ValueMap properties = (ValueMap)content.adaptTo(ValueMap.class);
return (Boolean)properties.get("cq:acApproved", (Object)false);
}
@Override
public void approve(Page newsletter) throws NewsletterException, PersistenceException {
this.check(newsletter);
Resource content = newsletter.getContentResource();
if (this.isApproved(newsletter)) {
throw new NewsletterException("Newsletter " + newsletter.getPath() + " has already been approved");
}
ModifiableValueMap properties = (ModifiableValueMap)content.adaptTo(ModifiableValueMap.class);
properties.put((Object)"cq:acApproved", (Object)true);
content.getResourceResolver().commit();
}
@Override
public void disapprove(Page newsletter) throws NewsletterException, PersistenceException {
this.check(newsletter);
Resource content = newsletter.getContentResource();
if (!this.isApproved(newsletter)) {
throw new NewsletterException("Newsletter " + newsletter.getPath() + " is currently not approved");
}
ModifiableValueMap properties = (ModifiableValueMap)content.adaptTo(ModifiableValueMap.class);
properties.put((Object)"cq:acApproved", (Object)false);
content.getResourceResolver().commit();
}
@Override
public void markAsSent(Page newsletter, String deliveryId) throws NewsletterException, PersistenceException {
this.check(newsletter);
Resource content = newsletter.getContentResource();
if (!this.isLinked(newsletter, deliveryId)) {
throw new NewsletterException("Newsletter " + newsletter.getPath() + " is not linked to delivery " + deliveryId);
}
ModifiableValueMap properties = (ModifiableValueMap)content.adaptTo(ModifiableValueMap.class);
if (properties.containsKey((Object)"cq:acSentBy")) {
throw new NewsletterException("Newsletter " + newsletter.getPath() + " has already been marked as sent");
}
properties.put((Object)"cq:acSentBy", (Object)deliveryId);
content.getResourceResolver().commit();
}
private LockManager getLockManager(Page newsletter) throws NewsletterException {
try {
Session session = ((Node)newsletter.adaptTo(Node.class)).getSession();
return session.getWorkspace().getLockManager();
}
catch (RepositoryException e) {
throw new NewsletterException("Could not retrieve lock manager", (Throwable)e);
}
}
private boolean isLocked(Page newsletter) throws NewsletterException {
LockManager lockManager = this.getLockManager(newsletter);
try {
return lockManager.isLocked(newsletter.getContentResource().getPath());
}
catch (RepositoryException e) {
throw new NewsletterException("Could not check lock", (Throwable)e);
}
}
@Override
public void lock(Page newsletter, String deliveryId) throws NewsletterException {
this.check(newsletter);
Resource content = newsletter.getContentResource();
if (!this.isLinked(newsletter, deliveryId)) {
throw new NewsletterException("Newsletter " + newsletter.getPath() + " is not linked to delivery " + deliveryId);
}
if (this.isLocked(newsletter)) {
throw new NewsletterException("Newsletter " + newsletter.getPath() + " is already locked");
}
LockManager lockManager = this.getLockManager(newsletter);
try {
Node node = (Node)content.adaptTo(Node.class);
node.addMixin("mix:lockable");
node.getSession().save();
lockManager.lock(content.getPath(), true, false, Long.MAX_VALUE, null);
ModifiableValueMap properties = (ModifiableValueMap)content.adaptTo(ModifiableValueMap.class);
properties.put((Object)"cq:acLockedBy", (Object)deliveryId);
content.getResourceResolver().commit();
}
catch (RepositoryException e) {
String msg = "Could not lock newsletter " + newsletter.getPath();
this.log.error(msg, (Throwable)e);
throw new NewsletterException(msg, (Throwable)e);
}
catch (PersistenceException e) {
String msg = "Could not write cq:acLockedBy";
this.log.warn(msg);
try {
lockManager.unlock(content.getPath());
}
catch (RepositoryException re) {
this.log.error("Could not undo locking of newsletter", (Throwable)re);
}
throw new NewsletterException(msg, (Throwable)e);
}
}
@Override
public void unlock(Page newsletter, String deliveryId) throws NewsletterException {
this.check(newsletter);
Resource content = newsletter.getContentResource();
if (!this.isLinked(newsletter, deliveryId)) {
throw new NewsletterException("Newsletter " + newsletter.getPath() + " is not linked to delivery " + deliveryId);
}
ModifiableValueMap properties = (ModifiableValueMap)content.adaptTo(ModifiableValueMap.class);
String storedDeliveryId = (String)properties.get("cq:acLockedBy", String.class);
if (storedDeliveryId == null || storedDeliveryId.isEmpty()) {
throw new NewsletterException("No associated delivery stored");
}
if (!storedDeliveryId.equals(deliveryId)) {
throw new NewsletterException("Newsletter " + newsletter.getPath() + " has been locked" + " using a different delivery, use the same delivery to unlock");
}
if (!this.isLocked(newsletter)) {
throw new NewsletterException("Newsletter " + newsletter.getPath() + " is currently not locked");
}
LockManager lockManager = this.getLockManager(newsletter);
try {
lockManager.unlock(content.getPath());
properties.remove((Object)"cq:acLockedBy");
content.getResourceResolver().commit();
}
catch (RepositoryException e) {
throw new NewsletterException("Could not unlock newsletter " + newsletter.getPath(), (Throwable)e);
}
catch (PersistenceException e) {
this.log.warn("Could not remove delivery property");
}
}
@Override
public void publish(Page newsletter) throws NewsletterException {
this.check(newsletter);
this.publisher.publish((Resource)newsletter.adaptTo(Resource.class));
}
protected void bindPublisher(Publisher publisher) {
this.publisher = publisher;
}
protected void unbindPublisher(Publisher publisher) {
if (this.publisher == publisher) {
this.publisher = null;
}
}
}