You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by di...@apache.org on 2021/06/07 13:32:50 UTC
[sling-whiteboard] 04/05: add sling sitemap invetory plugin
This is an automated email from the ASF dual-hosted git repository.
diru pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-whiteboard.git
commit 528118cdfda86493addb4e19a28d3e1e53a8047a
Author: Dirk Rudolph <di...@apache.org>
AuthorDate: Mon Jun 7 14:44:31 2021 +0200
add sling sitemap invetory plugin
---
sitemap/pom.xml | 6 +
.../java/org/apache/sling/sitemap/SitemapInfo.java | 10 +
.../sling/sitemap/impl/SitemapServiceImpl.java | 33 ++--
.../apache/sling/sitemap/impl/SitemapServlet.java | 12 +-
.../apache/sling/sitemap/impl/SitemapStorage.java | 16 +-
.../org/apache/sling/sitemap/impl/SitemapUtil.java | 23 ++-
.../impl/console/SitemapInventoryPlugin.java | 205 +++++++++++++++++++++
7 files changed, 275 insertions(+), 30 deletions(-)
diff --git a/sitemap/pom.xml b/sitemap/pom.xml
index 711bb03..0302154 100644
--- a/sitemap/pom.xml
+++ b/sitemap/pom.xml
@@ -166,6 +166,12 @@
<scope>provided</scope>
</dependency>
<dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.inventory</artifactId>
+ <version>1.0.6</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<scope>provided</scope>
diff --git a/sitemap/src/main/java/org/apache/sling/sitemap/SitemapInfo.java b/sitemap/src/main/java/org/apache/sling/sitemap/SitemapInfo.java
index da7caaa..6579b23 100644
--- a/sitemap/src/main/java/org/apache/sling/sitemap/SitemapInfo.java
+++ b/sitemap/src/main/java/org/apache/sling/sitemap/SitemapInfo.java
@@ -19,6 +19,7 @@
package org.apache.sling.sitemap;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.osgi.annotation.versioning.ProviderType;
/**
@@ -28,6 +29,15 @@ import org.osgi.annotation.versioning.ProviderType;
public interface SitemapInfo {
/**
+ * Returns a resource path to the node the sitemap is stored. May return null if the sitemap or sitemap-index is
+ * served on-demand.
+ *
+ * @return
+ */
+ @Nullable
+ String getStoragePath();
+
+ /**
* Returns the absolute, external url for the sitemap/sitemap-index.
*
* @return
diff --git a/sitemap/src/main/java/org/apache/sling/sitemap/impl/SitemapServiceImpl.java b/sitemap/src/main/java/org/apache/sling/sitemap/impl/SitemapServiceImpl.java
index 22e6111..aa3703c 100644
--- a/sitemap/src/main/java/org/apache/sling/sitemap/impl/SitemapServiceImpl.java
+++ b/sitemap/src/main/java/org/apache/sling/sitemap/impl/SitemapServiceImpl.java
@@ -25,6 +25,7 @@ import org.apache.sling.sitemap.SitemapInfo;
import org.apache.sling.sitemap.SitemapService;
import org.apache.sling.sitemap.common.SitemapLinkExternalizer;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.osgi.service.component.annotations.*;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.Designate;
@@ -58,7 +59,7 @@ public class SitemapServiceImpl implements SitemapService {
private static final Logger LOG = LoggerFactory.getLogger(SitemapServiceImpl.class);
@Reference(cardinality = ReferenceCardinality.OPTIONAL, policyOption = ReferencePolicyOption.GREEDY)
- private SitemapLinkExternalizer externalizer = SitemapLinkExternalizer.DEFAULT;
+ private SitemapLinkExternalizer externalizer;
@Reference
private JobManager jobManager;
@Reference
@@ -99,7 +100,7 @@ public class SitemapServiceImpl implements SitemapService {
return getSitemapUrlsForNestedSitemapRoot(sitemapRoot);
}
- String url = externalizer.externalize(sitemapRoot);
+ String url = externalize(sitemapRoot);
Collection<String> names = generatorManager.getGenerators(sitemapRoot).keySet();
if (url == null) {
@@ -121,7 +122,7 @@ public class SitemapServiceImpl implements SitemapService {
} else {
location += storageInfo.getSitemapSelector() + '.' + SitemapServlet.SITEMAP_EXTENSION;
}
- infos.add(newSitemapInfo(location, storageInfo.getSize(), storageInfo.getEntries()));
+ infos.add(newSitemapInfo(storageInfo.getPath(), location, storageInfo.getSize(), storageInfo.getEntries()));
}
return infos;
@@ -172,7 +173,7 @@ public class SitemapServiceImpl implements SitemapService {
private Collection<SitemapInfo> getSitemapUrlsForNestedSitemapRoot(Resource sitemapRoot) {
Collection<String> names = generatorManager.getGenerators(sitemapRoot).keySet();
Resource topLevelSitemapRoot = getTopLevelSitemapRoot(sitemapRoot);
- String topLevelSitemapRootUrl = externalizer.externalize(topLevelSitemapRoot);
+ String topLevelSitemapRootUrl = externalize(topLevelSitemapRoot);
if (topLevelSitemapRootUrl == null || names.isEmpty()) {
LOG.debug("Could not create absolute urls for nested sitemaps at: {}", sitemapRoot.getPath());
@@ -187,7 +188,7 @@ public class SitemapServiceImpl implements SitemapService {
String selector = getSitemapSelector(sitemapRoot, topLevelSitemapRoot, name);
String location = topLevelSitemapRootUrl + selector + '.' + SitemapServlet.SITEMAP_EXTENSION;
if (onDemandNames.contains(name)) {
- infos.add(newSitemapInfo(location, -1, -1));
+ infos.add(newSitemapInfo(null, location, -1, -1));
} else {
if (storageInfos == null) {
storageInfos = storage.getSitemaps(sitemapRoot, names);
@@ -197,7 +198,7 @@ public class SitemapServiceImpl implements SitemapService {
.findFirst();
if (storageInfoOpt.isPresent()) {
SitemapStorageInfo storageInfo = storageInfoOpt.get();
- infos.add(newSitemapInfo(location, storageInfo.getSize(), storageInfo.getEntries()));
+ infos.add(newSitemapInfo(storageInfo.getPath(), location, storageInfo.getSize(), storageInfo.getEntries()));
}
}
}
@@ -205,25 +206,29 @@ public class SitemapServiceImpl implements SitemapService {
return infos;
}
-
+ private String externalize(Resource resource) {
+ return (externalizer == null ? SitemapLinkExternalizer.DEFAULT : externalizer).externalize(resource);
+ }
private SitemapInfo newSitemapIndexInfo(@NotNull String url) {
- return new SitemapInfoImpl(url, -1, -1, true, true);
+ return new SitemapInfoImpl(null, url, -1, -1, true, true);
}
- private SitemapInfo newSitemapInfo(@NotNull String url, int size, int entries) {
- return new SitemapInfoImpl(url, size, entries, false, isWithinLimits(size, entries));
+ private SitemapInfo newSitemapInfo(@Nullable String path, @NotNull String url, int size, int entries) {
+ return new SitemapInfoImpl(path, url, size, entries, false, isWithinLimits(size, entries));
}
private static class SitemapInfoImpl implements SitemapInfo {
private final String url;
+ private final String path;
private final int size;
private final int entries;
private final boolean isIndex;
private final boolean withinLimits;
- private SitemapInfoImpl(@NotNull String url, int size, int entries, boolean isIndex, boolean withinLimits) {
+ private SitemapInfoImpl(@Nullable String path, @NotNull String url, int size, int entries, boolean isIndex, boolean withinLimits) {
+ this.path = path;
this.url = url;
this.size = size;
this.entries = entries;
@@ -231,6 +236,12 @@ public class SitemapServiceImpl implements SitemapService {
this.withinLimits = withinLimits;
}
+ @Nullable
+ @Override
+ public String getStoragePath() {
+ return path;
+ }
+
@NotNull
@Override
public String getUrl() {
diff --git a/sitemap/src/main/java/org/apache/sling/sitemap/impl/SitemapServlet.java b/sitemap/src/main/java/org/apache/sling/sitemap/impl/SitemapServlet.java
index a254a10..a7828b1 100644
--- a/sitemap/src/main/java/org/apache/sling/sitemap/impl/SitemapServlet.java
+++ b/sitemap/src/main/java/org/apache/sling/sitemap/impl/SitemapServlet.java
@@ -79,7 +79,7 @@ public class SitemapServlet extends SlingSafeMethodsServlet {
};
@Reference(cardinality = ReferenceCardinality.OPTIONAL, policyOption = ReferencePolicyOption.GREEDY)
- private SitemapLinkExternalizer externalizer = SitemapLinkExternalizer.DEFAULT;
+ private SitemapLinkExternalizer externalizer;
@Reference
private SitemapGeneratorManager generatorManager;
@Reference
@@ -134,8 +134,8 @@ public class SitemapServlet extends SlingSafeMethodsServlet {
// add any sitemap from the storage
for (SitemapStorageInfo storageInfo : storage.getSitemaps(topLevelSitemapRoot)) {
if (!addedSitemapSelectors.contains(storageInfo.getSitemapSelector())) {
- String location = externalizer.externalize(request, getSitemapLink(topLevelSitemapRoot,
- storageInfo.getSitemapSelector()));
+ String location = externalize(request,
+ getSitemapLink(topLevelSitemapRoot, storageInfo.getSitemapSelector()));
Calendar lastModified = storageInfo.getLastModified();
if (location != null && lastModified != null) {
sitemapIndex.addSitemap(location, lastModified.toInstant());
@@ -209,7 +209,7 @@ public class SitemapServlet extends SlingSafeMethodsServlet {
// applicable names we may serve directly, not applicable names, if any, we have to serve from storage
for (String applicableName : applicableNames) {
String sitemapSelector = getSitemapSelector(sitemapRoot, sitemapRoot, applicableName);
- String location = externalizer.externalize(request, getSitemapLink(sitemapRoot, sitemapSelector));
+ String location = externalize(request, getSitemapLink(sitemapRoot, sitemapSelector));
if (location != null) {
index.addSitemap(location);
addedSitemapSelectors.add(sitemapSelector);
@@ -222,6 +222,10 @@ public class SitemapServlet extends SlingSafeMethodsServlet {
return addedSitemapSelectors;
}
+ private String externalize(SlingHttpServletRequest request, String uri) {
+ return (externalizer == null ? SitemapLinkExternalizer.DEFAULT : externalizer).externalize(request, uri);
+ }
+
private static String getSitemapLink(Resource sitemapRoot, String sitemapSelector) {
String link = sitemapRoot.getPath() + '.' + SITEMAP_SELECTOR + '.';
if (SITEMAP_SELECTOR.equals(sitemapSelector)) {
diff --git a/sitemap/src/main/java/org/apache/sling/sitemap/impl/SitemapStorage.java b/sitemap/src/main/java/org/apache/sling/sitemap/impl/SitemapStorage.java
index 4ffa9c4..e6f41ea 100644
--- a/sitemap/src/main/java/org/apache/sling/sitemap/impl/SitemapStorage.java
+++ b/sitemap/src/main/java/org/apache/sling/sitemap/impl/SitemapStorage.java
@@ -51,7 +51,7 @@ import static org.apache.sling.sitemap.impl.SitemapUtil.*;
service = {SitemapStorage.class, Runnable.class},
property = {
Scheduler.PROPERTY_SCHEDULER_NAME + "=sitemap-storage-cleanup",
- Scheduler.PROPERTY_SCHEDULER_CONCURRENT + "=false",
+ Scheduler.PROPERTY_SCHEDULER_CONCURRENT + ":Boolean=false",
Scheduler.PROPERTY_SCHEDULER_RUN_ON + "=" + Scheduler.VALUE_RUN_ON_SINGLE
}
)
@@ -125,7 +125,7 @@ public class SitemapStorage implements Runnable {
}
@NotNull
- ValueMap getState(@NotNull Resource sitemapRoot, @NotNull String name) throws IOException {
+ public ValueMap getState(@NotNull Resource sitemapRoot, @NotNull String name) throws IOException {
String statePath = getSitemapFilePath(sitemapRoot, name) + STATE_EXTENSION;
try (ResourceResolver resolver = resourceResolverFactory.getServiceResourceResolver(AUTH)) {
Resource state = resolver.getResource(statePath);
@@ -142,7 +142,7 @@ public class SitemapStorage implements Runnable {
}
}
- void writeState(@NotNull Resource sitemapRoot, @NotNull String name, @NotNull Map<String, Object> state)
+ public void writeState(@NotNull Resource sitemapRoot, @NotNull String name, @NotNull Map<String, Object> state)
throws IOException {
String statePath = getSitemapFilePath(sitemapRoot, name) + STATE_EXTENSION;
try (ResourceResolver resolver = resourceResolverFactory.getServiceResourceResolver(AUTH)) {
@@ -170,7 +170,7 @@ public class SitemapStorage implements Runnable {
}
}
- void removeState(@NotNull Resource sitemapRoot, @NotNull String name) throws IOException {
+ public void removeState(@NotNull Resource sitemapRoot, @NotNull String name) throws IOException {
String statePath = getSitemapFilePath(sitemapRoot, name) + STATE_EXTENSION;
try (ResourceResolver resolver = resourceResolverFactory.getServiceResourceResolver(AUTH)) {
Resource stateResource = resolver.getResource(statePath);
@@ -183,7 +183,7 @@ public class SitemapStorage implements Runnable {
}
}
- String writeSitemap(@NotNull Resource sitemapRoot, @NotNull String name, @NotNull InputStream data, int size,
+ public String writeSitemap(@NotNull Resource sitemapRoot, @NotNull String name, @NotNull InputStream data, int size,
int entries) throws IOException {
String sitemapFilePath = getSitemapFilePath(sitemapRoot, name);
String statePath = sitemapFilePath + STATE_EXTENSION;
@@ -227,7 +227,7 @@ public class SitemapStorage implements Runnable {
return sitemapFilePath;
}
- Set<SitemapStorageInfo> getSitemaps(Resource sitemapRoot) {
+ public Set<SitemapStorageInfo> getSitemaps(Resource sitemapRoot) {
return getSitemaps(sitemapRoot, Collections.emptySet());
}
@@ -242,7 +242,7 @@ public class SitemapStorage implements Runnable {
* @param names
* @return
*/
- Set<SitemapStorageInfo> getSitemaps(Resource sitemapRoot, Collection<String> names) {
+ public Set<SitemapStorageInfo> getSitemaps(Resource sitemapRoot, Collection<String> names) {
Resource topLevelSitemapRoot = getTopLevelSitemapRoot(sitemapRoot);
Predicate<SitemapStorageInfo> filter;
@@ -279,7 +279,7 @@ public class SitemapStorage implements Runnable {
}
}
- boolean copySitemap(Resource sitemapRoot, String sitemapSelector, OutputStream output) throws IOException {
+ public boolean copySitemap(Resource sitemapRoot, String sitemapSelector, OutputStream output) throws IOException {
if (!isTopLevelSitemapRoot(sitemapRoot)) {
return false;
}
diff --git a/sitemap/src/main/java/org/apache/sling/sitemap/impl/SitemapUtil.java b/sitemap/src/main/java/org/apache/sling/sitemap/impl/SitemapUtil.java
index e5607bc..7ee438e 100644
--- a/sitemap/src/main/java/org/apache/sling/sitemap/impl/SitemapUtil.java
+++ b/sitemap/src/main/java/org/apache/sling/sitemap/impl/SitemapUtil.java
@@ -19,10 +19,11 @@
package org.apache.sling.sitemap.impl;
import org.apache.jackrabbit.JcrConstants;
+import org.apache.jackrabbit.util.ISO9075;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.sitemap.generator.SitemapGenerator;
import org.apache.sling.sitemap.SitemapService;
+import org.apache.sling.sitemap.generator.SitemapGenerator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -31,6 +32,8 @@ import java.util.*;
public class SitemapUtil {
+ private static final String JCR_SYSTEM_PATH = "/" + JcrConstants.JCR_SYSTEM + "/";
+
private SitemapUtil() {
super();
}
@@ -151,12 +154,16 @@ public class SitemapUtil {
*/
@NotNull
public static Iterator<Resource> findSitemapRoots(ResourceResolver resolver, String searchPath) {
- return new Iterator<Resource>() {
+ String correctedSearchPath = searchPath == null ? "/" : searchPath;
+ StringBuilder query = new StringBuilder(correctedSearchPath.length() + 35);
+ query.append("/jcr:root").append(ISO9075.encodePath(correctedSearchPath));
+ if (!correctedSearchPath.endsWith("/")) {
+ query.append('/');
+ }
+ query.append("/*[@").append(SitemapService.PROPERTY_SITEMAP_ROOT).append('=').append(Boolean.TRUE).append(']');
- private final Iterator<Resource> hits = resolver.findResources(
- "/jcr:root" + searchPath + "//*[@" + SitemapService.PROPERTY_SITEMAP_ROOT + "=true]",
- Query.XPATH
- );
+ return new Iterator<Resource>() {
+ private final Iterator<Resource> hits = resolver.findResources(query.toString(), Query.XPATH);
private Resource next = seek();
private Resource seek() {
@@ -165,7 +172,9 @@ public class SitemapUtil {
// skip a hit on the given searchPath itself. This may be when a search is done for descendant
// sitemaps given the normalized sitemap root path and the sitemap root's jcr:content is in the
// result set.
- if (nextHit == null || nextHit.getPath().equals(searchPath)) {
+ if (nextHit == null
+ || nextHit.getPath().equals(correctedSearchPath)
+ || nextHit.getPath().startsWith(JCR_SYSTEM_PATH)) {
continue;
}
return nextHit;
diff --git a/sitemap/src/main/java/org/apache/sling/sitemap/impl/console/SitemapInventoryPlugin.java b/sitemap/src/main/java/org/apache/sling/sitemap/impl/console/SitemapInventoryPlugin.java
new file mode 100644
index 0000000..8feb7bd
--- /dev/null
+++ b/sitemap/src/main/java/org/apache/sling/sitemap/impl/console/SitemapInventoryPlugin.java
@@ -0,0 +1,205 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+package org.apache.sling.sitemap.impl.console;
+
+import org.apache.felix.inventory.Format;
+import org.apache.felix.inventory.InventoryPrinter;
+import org.apache.sling.api.resource.LoginException;
+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.commons.scheduler.Scheduler;
+import org.apache.sling.sitemap.SitemapInfo;
+import org.apache.sling.sitemap.SitemapService;
+import org.apache.sling.sitemap.impl.SitemapUtil;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Map;
+
+@Component(
+ service = InventoryPrinter.class,
+ property = {
+ InventoryPrinter.NAME + "=slingsitemap",
+ InventoryPrinter.TITLE + "=Sling Sitemap",
+ InventoryPrinter.FORMAT + "=JSON",
+ InventoryPrinter.FORMAT + "=TEXT",
+ InventoryPrinter.WEBCONSOLE + "=true"
+
+ }
+)
+public class SitemapInventoryPlugin implements InventoryPrinter {
+
+ private static final Map<String, Object> AUTH = Collections.singletonMap(
+ ResourceResolverFactory.SUBSERVICE, "sitemap-reader");
+ private static final Logger LOG = LoggerFactory.getLogger(SitemapInventoryPlugin.class);
+
+ @Reference
+ private SitemapService sitemapService;
+ @Reference
+ private ResourceResolverFactory resourceResolverFactory;
+
+ private BundleContext bundleContext;
+
+ @Activate
+ protected void activate(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+
+ @Override
+ public void print(PrintWriter printWriter, Format format, boolean isZip) {
+ if (Format.JSON.equals(format)) {
+ printJson(printWriter);
+ } else if (Format.TEXT.equals(format)) {
+ printText(printWriter);
+ }
+ }
+
+ private void printJson(PrintWriter pw) {
+ pw.print('{');
+ pw.print("\"schedulers\":[");
+ boolean hasScheduler = false;
+ for (ServiceReference<?> ref : bundleContext.getBundle().getRegisteredServices()) {
+ Object schedulerExp = ref.getProperty(Scheduler.PROPERTY_SCHEDULER_EXPRESSION);
+ Object schedulerName = ref.getProperty(Scheduler.PROPERTY_SCHEDULER_NAME);
+ if (schedulerExp instanceof String && schedulerName instanceof String) {
+ if (hasScheduler) {
+ pw.print(',');
+ }
+ hasScheduler = true;
+ pw.print("{\"name\":\"");
+ pw.print(escapeDoubleQuotes((String) schedulerName));
+ pw.print("\",\"expression\":\"");
+ pw.print(escapeDoubleQuotes((String) schedulerExp));
+ pw.print("\"}");
+ }
+ }
+ pw.print("],");
+
+ pw.print("\"roots\":{");
+ try (ResourceResolver resolver = resourceResolverFactory.getServiceResourceResolver(AUTH)) {
+ Iterator<Resource> roots = SitemapUtil.findSitemapRoots(resolver, "/");
+ while (roots.hasNext()) {
+ Resource root = roots.next();
+ pw.print('"');
+ pw.print(escapeDoubleQuotes(root.getPath()));
+ pw.print("\":[");
+ Iterator<SitemapInfo> infoIt = sitemapService.getSitemapInfo(root).iterator();
+ while (infoIt.hasNext()) {
+ SitemapInfo info = infoIt.next();
+ pw.print('{');
+ pw.print("\"url\":\"");
+ pw.print(escapeDoubleQuotes(info.getUrl()));
+ pw.print('"');
+ if (info.getStoragePath() != null) {
+ pw.print(",\"path\":\"");
+ pw.print(escapeDoubleQuotes(info.getStoragePath()));
+ pw.print("\",\"size\":");
+ pw.print(info.getSize());
+ pw.print(",\"entries\":");
+ pw.print(info.getEntries());
+ pw.print(",\"inLimits\":");
+ pw.print(info.isWithinLimits());
+ }
+ pw.print('}');
+ if (infoIt.hasNext()) {
+ pw.print(',');
+ }
+ }
+ pw.print(']');
+ if (roots.hasNext()) {
+ pw.print(',');
+ }
+ }
+ } catch (LoginException ex) {
+ pw.println("Failed to list sitemaps: " + ex.getMessage());
+ LOG.warn("Failed to get inventory of sitemaps: {}", ex.getMessage(), ex);
+ }
+ pw.print('}');
+ pw.print('}');
+ }
+
+ private void printText(PrintWriter pw) {
+ pw.println("Apache Sling Sitemap Schedulers");
+ pw.println("-------------------------------");
+
+ for (ServiceReference<?> ref : bundleContext.getBundle().getRegisteredServices()) {
+ Object schedulerExp = ref.getProperty(Scheduler.PROPERTY_SCHEDULER_EXPRESSION);
+ Object schedulerName = ref.getProperty(Scheduler.PROPERTY_SCHEDULER_NAME);
+ if (schedulerExp != null && schedulerName != null) {
+ pw.print(" - Name: ");
+ pw.print(schedulerName);
+ pw.println();
+ pw.print(" Expression: ");
+ pw.print(schedulerExp);
+ pw.println();
+ }
+ }
+
+ pw.println();
+ pw.println();
+ pw.println("Apache Sling Sitemap Roots");
+ pw.println("--------------------------");
+
+ try (ResourceResolver resolver = resourceResolverFactory.getServiceResourceResolver(AUTH)) {
+ Iterator<Resource> roots = SitemapUtil.findSitemapRoots(resolver, "/");
+ while (roots.hasNext()) {
+ Resource root = roots.next();
+ pw.print(root.getPath());
+ pw.print(':');
+ pw.println();
+ for (SitemapInfo info : sitemapService.getSitemapInfo(root)) {
+ pw.print(" - Url: ");
+ pw.print(info.getUrl());
+ pw.println();
+ if (info.getStoragePath() != null) {
+ pw.print(" Path: ");
+ pw.print(info.getStoragePath());
+ pw.println();
+ pw.print(" Bytes: ");
+ pw.print(info.getSize());
+ pw.println();
+ pw.print(" Urls: ");
+ pw.print(info.getEntries());
+ pw.println();
+ pw.print(" Within Limits: ");
+ pw.print(info.isWithinLimits() ? "yes": "no");
+ pw.println();
+ }
+ }
+ }
+ } catch (LoginException ex) {
+ pw.println("Failed to list sitemaps: " + ex.getMessage());
+ LOG.warn("Failed to get inventory of sitemaps: {}", ex.getMessage(), ex);
+ }
+ }
+
+ private static String escapeDoubleQuotes(String text) {
+ return text.replace("\"", "\\\"");
+ }
+}