/*
* (C) Copyright 2015 Netcentric AG.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package biz.netcentric.cq.tools.actool.configuploadlistener.impl;
import java.util.Map;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.observation.Event;
import javax.jcr.observation.EventIterator;
import javax.jcr.observation.EventListener;
import org.apache.commons.lang.StringUtils;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.PropertyOption;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.commons.osgi.PropertiesUtil;
import org.apache.sling.jcr.api.SlingRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import biz.netcentric.cq.tools.actool.aceservice.AceService;
import biz.netcentric.cq.tools.actool.configuploadlistener.UploadListenerService;
import biz.netcentric.cq.tools.actool.helper.Constants;
import biz.netcentric.cq.tools.actool.history.AcHistoryService;
@Component(metatype = true, label = "AC Configuration Upload Listener Service", immediate = true, description = "Listens for ACL configuration uploads and triggers ACL Service.")
@Properties({
@Property(label = "Service status", name = UploadListenerServiceImpl.ACE_UPLOAD_LISTENER_SET_STATUS_SERVICE, options = {
@PropertyOption(name = "disabled", value = "disabled"),
@PropertyOption(name = "enabled", value = "enabled") }) })
@Service(value = UploadListenerService.class)
public class UploadListenerServiceImpl implements UploadListenerService,
EventListener {
static final String ACE_UPLOAD_LISTENER_SET_STATUS_SERVICE = "AceUploadListener.setStatusService";
private String configurationPath;
private boolean enabled;
private static final Logger LOG = LoggerFactory
.getLogger(UploadListenerServiceImpl.class);
private Session adminSession;
@Reference
SlingRepository repository;
@Reference
AceService aceService;
@Reference
AcHistoryService acHistoryService;
@Override
public void onEvent(EventIterator events) {
if (this.enabled) {
int changes = 0; // Number of new or changed files.
try {
while (events.hasNext()) {
Event event = events.nextEvent();
Node node = null;
switch (event.getType()) {
case Event.NODE_ADDED:
node = adminSession.getNode(event.getPath());
break;
case Event.PROPERTY_CHANGED:
if (event.getPath().endsWith("jcr:content/jcr:data")) {
node = adminSession.getNode(event.getPath().replace("/jcr:content/jcr:data", ""));
}
break;
default:
LOG.warn("Unexpected event: {}", event);
}
if (node != null && node.hasProperty("jcr:content/jcr:data")) {
LOG.info("Detected new or changed node at {}.", node.getPath());
++changes;
} else {
LOG.debug("Node {} associated with event does not have configuration data.", event.getPath());
}
}
} catch (RepositoryException e) {
LOG.error("Error while handling events.", e);
}
if (changes > 0) {
LOG.info("There are {} new or changed files. Triggering reload of configuration.", changes);
aceService.execute();
}
}
}
@Activate
public void activate(@SuppressWarnings("rawtypes") final Map properties)
throws Exception {
this.configurationPath = aceService.getConfiguredAcConfigurationRootPath();
String statusService = PropertiesUtil
.toString(
properties
.get(UploadListenerServiceImpl.ACE_UPLOAD_LISTENER_SET_STATUS_SERVICE),
"");
if (StringUtils.equals(statusService, "enabled")) {
this.enabled = true;
} else {
this.enabled = false;
}
setEventListener();
}
private void setEventListener() throws Exception {
if (StringUtils.isNotBlank(this.configurationPath)) {
try {
adminSession = repository.loginService(Constants.USER_AC_SERVICE, null);
adminSession
.getWorkspace()
.getObservationManager()
.addEventListener(
this, // handler
// Event.PROPERTY_ADDED|Event.NODE_ADDED,
// //binary combination of event types
Event.NODE_ADDED | Event.PROPERTY_CHANGED,
this.configurationPath, // path
true, // is Deep?
null, // uuids filter
null, // nodetypes filter
false);
LOG.info(
"added EventListener for ACE configuration root path: {}",
this.configurationPath);
} catch (RepositoryException e) {
LOG.error("RepositoryException in UploadListenerService:{}", e);
}
} else {
LOG.warn("no root ACE configuration path configured in AceService");
}
}
@Deactivate
public void deactivate() {
if (adminSession != null) {
adminSession.logout();
}
}
public void setPath(String path) {
this.configurationPath = path;
try {
setEventListener();
} catch (Exception e) {
LOG.error("Exception in UploadListenerService: {}", e);
}
}
}