/* * #%L * ACS AEM Commons Bundle * %% * Copyright (C) 2014 Adobe * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * #L% */ package com.adobe.acs.commons.wcm.impl; import java.io.IOException; import java.io.PrintWriter; import java.util.Calendar; import java.util.Collections; import java.util.Date; import java.util.Iterator; import java.util.Map; import javax.jcr.Node; import javax.jcr.NodeIterator; import javax.jcr.Session; import javax.jcr.query.Query; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Properties; 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.api.resource.Resource; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.api.resource.ResourceResolverFactory; import org.apache.sling.api.resource.ValueMap; /** * Web console plugin which allows for management of users WCM Notification Inboxes. */ @SuppressWarnings("serial") @Component @Service @Properties({ @Property(name = "felix.webconsole.label", value = "wcm-inbox"), @Property(name = "felix.webconsole.title", value = "WCM Inbox") }) public class WCMInboxWebConsolePlugin extends HttpServlet { @Reference private ResourceResolverFactory rrFactory; private static final String SERVICE_NAME = "wcm-inbox-cleanup"; private static final Map<String, Object> AUTH_INFO; static { AUTH_INFO = Collections.singletonMap(ResourceResolverFactory.SUBSERVICE, (Object) SERVICE_NAME); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Calendar cal = Calendar.getInstance(); cal.add(Calendar.DAY_OF_MONTH, -1); Date yesterday = cal.getTime(); PrintWriter pw = resp.getWriter(); ResourceResolver resolver = null; try { resolver = rrFactory.getServiceResourceResolver(AUTH_INFO); pw.println("<p class='statline ui-state-highlight'>Inbox Notification Configurations</p>"); pw.println("<ul>"); @SuppressWarnings("deprecation") Iterator<Resource> configured = resolver .findResources( "/jcr:root//element(*, rep:User)/wcm/notification/config/subscriptions/element(*)[@channel='inbox']", Query.XPATH); while (configured.hasNext()) { String path = configured.next().getPath(); pw.println("<li>"); pw.printf("<a target='_new' href='/crx/de/index.jsp#%s'>%s</a>", path, path); pw.println("</li>"); } pw.println("</ul>"); pw.println("<br/>"); pw.println("<p class='statline ui-state-highlight'>Inbox Notification Sizes</p>"); pw.println("<table class='content'>"); pw.println("<tr><th class='content'>Path</th><th class='content'>Count</th><th class='content'>In Last 24 Hours</th><th></th></tr>"); @SuppressWarnings("deprecation") Iterator<Resource> inboxes = resolver.findResources( "/jcr:root//element(*, rep:User)/wcm/notification/inbox", Query.XPATH); while (inboxes.hasNext()) { Resource inbox = inboxes.next(); long[] childCount = countChildren(inbox, yesterday); pw.printf( "<tr><td class='content'>%s</td><td class='content'>%s</td><td class='content'>%s</td><td><form method='POST' action=''><input type='hidden' name='path' value='%s'><input type='submit' value='Clear'></form></td></tr>%n", inbox.getPath(), childCount[0], childCount[1], inbox.getPath()); } pw.println("</table>"); } catch (Exception e) { throw new ServletException(e); } finally { if (resolver != null && resolver.isLive()) { resolver.close(); } } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String path = req.getParameter("path"); if (path != null) { ResourceResolver resolver = null; try { int counter = 0; resolver = rrFactory.getServiceResourceResolver(AUTH_INFO); Session session = resolver.adaptTo(Session.class); Node node = session.getNode(path); NodeIterator it = node.getNodes(); while (it.hasNext()) { it.nextNode().remove(); counter++; } session.save(); resp.getWriter().printf("<p class='statline ui-state-error'>Deleted %s notifications</p>%n", counter); } catch (Exception e) { throw new ServletException(e); } finally { if (resolver != null && resolver.isLive()) { resolver.close(); } } } resp.sendRedirect((String) req.getAttribute("felix.webconsole.pluginRoot")); } private long[] countChildren(Resource inbox, Date yesterday) { long counter = 0; long yesterdayCounter = 0; Iterator<Resource> children = inbox.listChildren(); while (children.hasNext()) { Resource child = children.next(); ValueMap map = child.adaptTo(ValueMap.class); Date date = map.get("modifiedDate", Date.class); if (date != null && date.after(yesterday)) { yesterdayCounter++; } counter++; } return new long[] { counter, yesterdayCounter }; } }