Groovy BinariesInfoScript
The BinariesInfoScript
The following updater script logs information about binaries, i.e. assets and/or images, that are selected by the given XPath query.
Description
Find assets and/or images based on size limits and output their primary type, mime type, size and path, plus the number of visited binaries and the number of binaries within the given limits.
XPath query
Set a query for binaries, i.e. JCR hippo:resource nodes.
E.g. all images:
content/gallery//element(*,hippo:resource)
E.g. all assets:
content/assets//element(*,hippo:resource)
E.g. all MS Excel assets:
content/assets//element(*,hippo:resource)[@jcr:mimeType="application/vnd.ms-excel"]
E.g. all pdf resources embedded in documents:
content/documents//element(*, hippo:resource)[@jcr:mimeType='application/pdf']
Parameters
{"lowerLimit": "1k", "upperLimit": "10M", "verbose": "true"} lowerLimit/upperLimit: lower and upper limits of the size of the binaries to find (optional, inclusive). Postfixes k, M and G are supported. verbose: true (default): outputs the list of binaries within the limits (showing primaryType, mimeType, size, path) and the summary false: outputs only the summary: number of visited binaries and number of binaries within the limits
Script
package org.hippoecm.frontend.plugins.cms.admin.updater import org.onehippo.repository.update.BaseNodeUpdateVisitor import javax.jcr.Node import javax.jcr.RepositoryException import javax.jcr.Session /** * Find binaries (assets or images) in the repository and output their type, mime type, path and size if their size lies * between the configured limits. * * XPath query (typically): content/assets//element(*,hippo:resource) * * Parameters: {"lowerLimit": "1k", "upperLimit": "10M", "verbose": "true"} * lowerLimit/upperLimit: lower and upper limits of the size of the binaries to find (optional, inclusive). * Postfixes k, M and G are supported. * verbose: true (default): outputs the list of binaries within the limits (showing primaryType, mimeType, size, path) * and the summary * false: outputs only the summary: number of visited binaries and number of binaries within the limits */ class BinariesInfoScript extends BaseNodeUpdateVisitor { Boolean verbose = null String configuredLowerLimit = null String configuredUpperLimit = null Long lowerLimit = null Long upperLimit = null List<BinariesInfo> binariesWithinLimits = new ArrayList<BinariesInfo>() int totalVisitedNodes = 0 void initialize(Session session) throws RepositoryException { verbose = !("false" == parametersMap.get("verbose")) configuredLowerLimit = parametersMap.get("lowerLimit") configuredUpperLimit = parametersMap.get("upperLimit") lowerLimit = getSize(configuredLowerLimit, 0L) upperLimit = getSize(configuredUpperLimit, Long.MAX_VALUE) log.info "BinariesInfoScript initialized with parameters lowerLimit=${configuredLowerLimit}, " + "upperLimit=${configuredUpperLimit}, verbose=${verbose}." } boolean logSkippedNodePaths() { return false // don't log skipped node paths } boolean skipCheckoutNodes() { return false // return true for readonly visitors and/or updates unrelated to versioned content } Node firstNode(final Session session) throws RepositoryException { return null // implement when using custom node selection/navigation } Node nextNode() throws RepositoryException { return null // implement when using custom node selection/navigation } boolean doUpdate(Node node) { totalVisitedNodes++ log.debug "BinariesInfoScript visiting node ${node.path} of type ${node.primaryNodeType.name}" if (node.hasProperty("jcr:data")) { long size = node.getProperty("jcr:data").getLength() if ((size >= lowerLimit) && (size <= upperLimit)) { final String primaryType = node.getProperty("jcr:primaryType").getString(); final String mimeType = node.hasProperty("jcr:mimeType") ? node.getProperty("jcr:mimeType").getString() : "none" binariesWithinLimits.add(new BinariesInfo(primaryType, mimeType, size, node.getPath())) } return true } log.warn "Unexpectedly, node ${node.getPath()} does not have property jcr:data" return false } boolean undoUpdate(Node node) { throw new UnsupportedOperationException('Updater does not implement undoUpdate method') } void destroy() { logOutput() } void logOutput() { StringBuilder sb = new StringBuilder() if (verbose && binariesWithinLimits.size() > 0) { sb.append("Detailed binaries information (primaryType, mimeType, size, path):\n") for (BinariesInfo info : binariesWithinLimits) { sb.append(" ").append(info.getPrimaryType()).append(", ").append(info.getMimeType()).append(", ") sb.append(info.getSize()).append(", ").append(info.getPath()).append("\n") } } sb.append("Summary of binaries information:\n") sb.append(" Total of visited binaries is ").append(totalVisitedNodes).append(".\n") sb.append(" Found ").append(binariesWithinLimits.size()).append(" binaries") sb.append(" larger than ").append(lowerLimit).append(" bytes") if ((configuredLowerLimit != null) && (configuredLowerLimit.length() > 0)) { sb.append(" (").append(configuredLowerLimit).append(")") } if (upperLimit != Long.MAX_VALUE) { sb.append(" and smaller than ").append(upperLimit).append(" bytes (").append(configuredUpperLimit).append(")") } sb.append(".\n") log.info(sb.toString()) } Long getSize(final String configuredSize, final Long defaultValue) { if ((configuredSize == null) || configuredSize.length() == 0) { return defaultValue } try { if (configuredSize.endsWith("G")) { return Long.parseLong(configuredSize.substring(0, configuredSize.length()-1)) * 1024 * 1024 * 1024; } else if (configuredSize.endsWith("M")) { return Long.parseLong(configuredSize.substring(0, configuredSize.length()-1)) * 1024 * 1024 } else if (configuredSize.endsWith("k")) { return Long.parseLong(configuredSize.substring(0, configuredSize.length()-1)) * 1024 } else { return Long.parseLong(configuredSize) } } catch (NumberFormatException nfe) { log.error("Configured size {} cannot be parsed into a long. Defaulting to {}", configuredSize, defaultValue); return defaultValue } } /** * Information about a found binary. */ class BinariesInfo { private final String primaryType private final String mimeType private final long size private final String path BinariesInfo(final String primaryType, final String mimeType, final long size, final String path) { this.primaryType = primaryType this.mimeType = mimeType this.size = size this.path = path } String getPrimaryType() { return primaryType } String getMimeType() { return mimeType } long getSize() { return size } String getPath() { return path } } }