<%-- ADOBE CONFIDENTIAL Copyright 2015 Adobe Systems Incorporated All Rights Reserved. NOTICE: All information contained herein is, and remains the property of Adobe Systems Incorporated and its suppliers, if any. The intellectual and technical concepts contained herein are proprietary to Adobe Systems Incorporated and its suppliers and may be covered by U.S. and Foreign Patents, patents in process, and are protected by trade secret or copyright law. Dissemination of this information or reproduction of this material is strictly forbidden unless prior written permission is obtained from Adobe Systems Incorporated. --%><% %><%@page import="org.apache.sling.api.resource.Resource, org.apache.sling.api.resource.ResourceUtil, org.apache.sling.api.resource.ValueMap, org.apache.sling.api.resource.ResourceResolver, org.apache.jackrabbit.api.security.user.User, org.apache.jackrabbit.api.security.user.Group, org.apache.jackrabbit.api.security.user.Authorizable, org.apache.commons.lang.StringUtils, org.apache.commons.io.FilenameUtils, java.util.Iterator, java.util.Arrays, java.util.List, java.util.ArrayList, java.util.Calendar, javax.jcr.lock.LockManager, javax.jcr.Node, javax.jcr.Session, com.adobe.granite.comments.CommentCollection, com.adobe.granite.comments.CommentManager, com.adobe.granite.ui.components.Config, com.day.cq.dam.api.DamConstants, com.day.cq.dam.api.Asset, com.day.cq.dam.api.Rendition, com.day.cq.dam.commons.util.S73DConstants, com.day.cq.dam.api.s7dam.constants.S7damConstants, com.day.cq.dam.commons.util.DamUtil, com.day.cq.dam.commons.util.S73DHelper, com.day.cq.dam.commons.util.S7SetHelper, com.day.cq.commons.LabeledResource, com.day.cq.commons.jcr.JcrConstants, com.day.cq.dam.commons.util.StockUtil, com.day.cq.dam.commons.util.UIHelper"%> <%@ page import="com.adobe.dam.print.ids.StringConstants" %> <% %><%@taglib prefix="cq" uri="http://www.day.com/taglibs/cq/1.0"%><%--### ASSET Base API ========= This JSP is included by spawned pages, hence it may gets called multiple time. This JSP should not evaluate or perform any execution task, rather it should only contain methods & configs to avoid performance overhead. ###--%><% //Attributes set by \contentrenderer\base\init\assetBase.jsp should be accessed through following constants. final String CAN_ANNOTATE = "com.adobe.cq.assets.contentrenderer.asset.canAnnotate"; final String CAN_EDIT = "com.adobe.cq.assets.contentrenderer.asset.canEdit"; final String CAN_FINDSIMILAR = "com.adobe.cq.assets.contentrenderer.asset.canFindSimilar"; final String HAS_FEATURES = "com.adobe.cq.assets.contentrenderer.asset.hasFeatures"; final String HAS_PREDICTED_TAGS = "com.adobe.cq.assets.contentrenderer.asset.hasPredictedTags"; final String IS_EDITABLE_PRINT_ASSET = "com.adobe.cq.assets.contentrenderer.asset.isEditablePrintAsset"; final String MANUAL_THUMBNAIL_ASSET = "com.adobe.cq.assets.contentrenderer.asset.manualThumbnailAsset"; final String REMOTE_THUMBNAIL = "com.adobe.cq.assets.contentrenderer.asset.remoteThumbnail"; //remote asset thumbnail when asset doesn't exist in JCR final String MIMETYPE = "com.adobe.cq.assets.contentrenderer.asset.mimeType"; final String S7_DAM_TYPE = "com.adobe.cq.assets.contentrenderer.asset.s7damType"; final String ASSET_LAST_MODIFICATION = "com.adobe.cq.assets.contentrenderer.asset.assetLastModification"; final String LAST_MODIFIED = "com.adobe.cq.assets.contentrenderer.asset.lastModified"; final String COMMENTS_COUNT = "com.adobe.cq.assets.contentrenderer.asset.commentsCount"; final String STATUS = "com.adobe.cq.assets.contentrenderer.asset.status"; final String IS_ASSETEXPIRED = "com.adobe.cq.assets.contentrenderer.asset.isAssetExpired"; final String IS_SUBASSET_EXPIRED = "com.adobe.cq.assets.contentrenderer.asset.isSubAssetExpired"; final String SIZE = "com.adobe.cq.assets.contentrenderer.asset.size"; final String RESOLUTION = "com.adobe.cq.assets.contentrenderer.asset.resolution"; final String AVERAGE_RATING = "com.adobe.cq.assets.contentrenderer.asset.averageRating"; final String CREATIVE_RATING = "com.adobe.cq.assets.contentrenderer.asset.creativeRating"; final String WIDTH = "com.adobe.cq.assets.contentrenderer.asset.width"; final String HEIGHT = "com.adobe.cq.assets.contentrenderer.asset.height"; final String BYTES = "com.adobe.cq.assets.contentrenderer.asset.bytes"; final String IS_DOWNLOAD_ALLOWED_FOR_ADMINS = "com.adobe.cq.assets.contentrenderer.asset.isAdmin"; final String IS_DOWNLOADABLE = "com.adobe.cq.assets.contentrenderer.asset.isDownloadable"; final String IS_DM_SET = "com.adobe.cq.assets.contentrenderer.asset.isDMSet"; final String DM_ASSET_TYPE = "com.adobe.cq.assets.contentrenderer.asset.dmAssetType"; final String ASSET_EXPIRY_TIME = "com.adobe.cq.assets.contentrenderer.asset.assetExpiryTime"; final String IS_CONTENT_FRAGMENT = "com.adobe.cq.assets.contentrenderer.asset.isContentFragment"; final String DYNAMIC_VIDEO = "com.adobe.cq.assets.contentrenderer.dynamicVideo"; // indicate if S7 BasicVideoViewer will be used for video final String IS_SNIPPET_TEMPLATE = "com.adobe.cq.assets.contentrenderer.asset.isSnippetTemplate"; // 3D Support final String IS_3D_ASSET = "com.adobe.cq.assets.contentrenderer.asset.is3D"; final String IS_MISSING_DEPENDENCIES = "com.adobe.cq.assets.contentrenderer.asset.isMissingDependencies"; final String IS_ARCHIVE = "com.adobe.cq.assets.contentrenderer.asset.isArchive"; final String IS_CHECKED_OUT = "com.adobe.cq.assets.contentrenderer.asset.isCheckedOut"; final String CAN_CHECK_OUT = "com.adobe.cq.assets.contentrenderer.asset.canCheckOut"; final String CAN_CHECK_IN = "com.adobe.cq.assets.contentrenderer.asset.canCheckIn"; final String CHECKED_OUT_BY = "com.adobe.cq.assets.contentrenderer.asset.checkedOutBy"; final String CHECKED_OUT_BY_FORMATTED = "com.adobe.cq.assets.contentrenderer.asset.checkedOutByFormatted"; final String CHECKED_OUT_BY_CURRENT_USER = "com.adobe.cq.assets.contentrenderer.asset.checkedOutByCurrentUser"; final String IS_PARENT_ASSET_CHECKED_OUT = "com.adobe.cq.assets.contentrenderer.asset.isParentAssetCheckedOut"; final String IS_PARENT_ASSET_CHECKED_OUT_BY_CURRENT_USER = "com.adobe.cq.assets.contentrenderer.asset.isParentAssetCheckedOutByCurrentUser"; final String IS_STOCK_ASSET = "com.adobe.cq.assets.contentrenderer.asset.isStockAsset"; final String IS_STOCK_ASSET_LICENSED = "com.adobe.cq.assets.contentrenderer.asset.isStockAssetLicensed"; final String STOCK_ACCESSIBLE = "com.adobe.cq.assets.contentrenderer.asset.isStockAccessible"; final String REMOTE_DAM_MOUNTPOINT = "com.adobe.cq.asset.contentrenderer.remoteasset.mountpoint"; %><%! private List getAssetActionRels(boolean hasJcrRead, boolean hasJcrWrite, boolean hasAddChild, boolean canEdit, boolean canAnnotate, boolean isAdmin, boolean isAssetExpired, boolean isSubAssetExpired) { return getAssetActionRels(hasJcrRead, hasJcrWrite, hasAddChild, canEdit, canAnnotate, isAdmin, isAssetExpired, isSubAssetExpired, false, false, false, true, false); } private List getAssetActionRels(boolean hasJcrRead, boolean hasJcrWrite, boolean hasAddChild, boolean canEdit, boolean canAnnotate, boolean isAdmin, boolean isAssetExpired, boolean isSubAssetExpired, boolean isContentFragment) { return getAssetActionRels(hasJcrRead, hasJcrWrite, hasAddChild, canEdit, canAnnotate, isAdmin, isAssetExpired, isSubAssetExpired, isContentFragment, false, false, true, false); } private List getAssetActionRels(boolean hasJcrRead, boolean hasJcrWrite, boolean hasAddChild, boolean canEdit, boolean canAnnotate, boolean isAdmin, boolean isAssetExpired, boolean isSubAssetExpired, boolean isContentFragment, boolean isArchive) { return getAssetActionRels(hasJcrRead, hasJcrWrite, hasAddChild, canEdit, canAnnotate, isAdmin, isAssetExpired, isSubAssetExpired, isContentFragment, isArchive, false, true, false); } private List getAssetActionRels(boolean hasJcrRead, boolean hasJcrWrite, boolean hasAddChild, boolean canEdit, boolean canAnnotate, boolean isAdmin, boolean isAssetExpired, boolean isSubAssetExpired, boolean isContentFragment, boolean isArchive, boolean isSnippetTemplate, boolean isDownloadable) { return getAssetActionRels(hasJcrRead, hasJcrWrite, hasAddChild, canEdit, canAnnotate, isAdmin, isAssetExpired, isSubAssetExpired, isContentFragment, isArchive, isSnippetTemplate, isDownloadable, true); } private List getAssetActionRels(boolean hasJcrRead, boolean hasJcrWrite, boolean hasAddChild, boolean canEdit, boolean canAnnotate, boolean isAdmin, boolean isAssetExpired, boolean isSubAssetExpired, boolean isContentFragment, boolean isArchive, boolean isSnippetTemplate, boolean isDownloadable, boolean isOmniSearchRequest) { return getAssetActionRels(hasJcrRead, hasJcrWrite, hasAddChild, canEdit, canAnnotate, isAdmin, isAssetExpired, isSubAssetExpired, isContentFragment, isArchive, isSnippetTemplate, isDownloadable, isOmniSearchRequest, false, false, false); } /** * @Deprecated in AEM 6.4.4 here for backward compatibility, use UIHelper.getAssetActionRels instead */ private List getAssetActionRels(boolean hasJcrRead, boolean hasJcrWrite, boolean hasAddChild, boolean canEdit, boolean canAnnotate, boolean isAdmin, boolean isAssetExpired, boolean isSubAssetExpired, boolean isContentFragment, boolean isArchive, boolean isSnippetTemplate, boolean isDownloadable, boolean isOmniSearchRequest, boolean isStockAsset, boolean isStockAssetLicensed, boolean isStockAccessible) { return getAssetActionRels(hasJcrRead, hasJcrWrite, hasAddChild, canEdit, canAnnotate, isAdmin, isAssetExpired, isSubAssetExpired, isContentFragment, isArchive, isSnippetTemplate, isDownloadable, isOmniSearchRequest, isStockAsset, isStockAssetLicensed, isStockAccessible, false); } private List getAssetActionRels(boolean hasJcrRead, boolean hasJcrWrite, boolean hasAddChild, boolean canEdit, boolean canAnnotate, boolean isAdmin, boolean isAssetExpired, boolean isSubAssetExpired, boolean isContentFragment, boolean isArchive, boolean isSnippetTemplate, boolean isDownloadable, boolean isOmniSearchRequest, boolean isStockAsset, boolean isStockAssetLicensed, boolean isStockAccessible, boolean isCFLaunchEnabled) { return getAssetActionRels(hasJcrRead, hasJcrWrite, hasAddChild, canEdit, canAnnotate, isAdmin, isAssetExpired, isSubAssetExpired, isContentFragment, isArchive, isSnippetTemplate, isDownloadable, isOmniSearchRequest, isStockAsset, isStockAssetLicensed, isStockAccessible, isCFLaunchEnabled, false); } private List getAssetActionRels(boolean hasJcrRead, boolean hasJcrWrite, boolean hasAddChild, boolean canEdit, boolean canAnnotate, boolean isAdmin, boolean isAssetExpired, boolean isSubAssetExpired, boolean isContentFragment, boolean isArchive, boolean isSnippetTemplate, boolean isDownloadable, boolean isOmniSearchRequest, boolean isStockAsset, boolean isStockAssetLicensed, boolean isStockAccessible, boolean isCFLaunchEnabled, boolean isMsmCfEnabled) { List actionRels = new ArrayList(); actionRels.add("cq-damadmin-admin-actions-createworkflow"); if(isContentFragment && isOmniSearchRequest) { actionRels.add("aem-assets-admin-actions-edit-fragment-activator"); if(isCFLaunchEnabled) { actionRels.add("cq-damadmin-admin-actions-createlaunch"); } } if (hasJcrRead) { if (!isContentFragment) { actionRels.add("foundation-damadmin-properties-activator"); } else { actionRels.add("foundation-damadmin-fragmentprops-activator"); } actionRels.add("cq-damadmin-admin-actions-add-to-collection-activator"); actionRels.add("cq-damadmin-admin-actions-desktop-activator"); actionRels.add("cq-damadmin-admin-actions-opendesktop"); actionRels.add("cq-damadmin-admin-actions-editdesktop"); actionRels.add("cq-damadmin-admin-actions-revealdesktop"); actionRels.add("aem-assets-admin-actions-moderatetags-activator"); } if (hasJcrWrite) { actionRels.add("cq-damadmin-admin-actions-open-activator"); actionRels.add("aem-assets-admin-actions-shoppableedit-activator"); actionRels.add("cq-damadmin-admin-actions-createversion"); actionRels.add("dam-asset-reprocessassets-action-activator"); if (!isContentFragment) { actionRels.add("cq-damadmin-admin-actions-createlivecopy"); actionRels.add("cq-siteadmin-admin-actions-relate-activator"); actionRels.add("cq-siteadmin-admin-actions-unrelate-activator"); } else { if (isMsmCfEnabled) { actionRels.add("cq-damadmin-admin-actions-createlivecopy"); } if (isCFLaunchEnabled) { actionRels.add("cq-damadmin-admin-actions-createlaunch"); } } } if (hasAddChild) { actionRels.add("cq-damadmin-admin-actions-open-activator"); actionRels.add("icon-note"); } // Content Fragment Editor can be viewed in "read-only mode" if user cannot edit. if ((canEdit || isContentFragment) && (isAdmin || !isAssetExpired)) { if(!isContentFragment || !isOmniSearchRequest) { actionRels.add("aem-assets-admin-actions-edit-activator"); } actionRels.add("dam-assetedit-action-select"); } if (canAnnotate) { actionRels.add("aem-assets-admin-actions-annotate-activator"); actionRels.add("cq-project-admin-actions-annotate-activator"); } if ((isAdmin || (!isAssetExpired && !isSubAssetExpired)) && isDownloadable) { if (!isContentFragment) { actionRels.add("cq-damadmin-admin-actions-download-activator"); } else { actionRels.add("cq-damadmin-admin-actions-downloadcf-activator"); } } if (isArchive) { actionRels.add("cq-damadmin-admin-actions-extract-activator"); } if (hasJcrWrite && isSnippetTemplate) { actionRels.add("cq-damadmin-admin-actions-createsnippet-activator"); } if (isStockAccessible && isStockAsset) { actionRels.add("cq-damadmin-admin-actions-stock-viewsimilar-activator"); actionRels.add("cq-damadmin-admin-actions-stock-viewexternal-activator"); if (!isStockAssetLicensed) { actionRels.add("cq-damadmin-admin-actions-stock-license-activator"); } else { actionRels.add("cq-damadmin-admin-actions-stock-licenseagain-activator"); } } return actionRels; } private boolean isArchive(Resource metadataResc) { String format = ResourceUtil.getValueMap(metadataResc).get("dc:format", ""); return format.equals("application/zip"); } private boolean isEditablePrintAsset(Node resourceNode) { try { return isIdsTemplateAsset(resourceNode); } catch (Exception ex) { log("Exception occurred while checking whether the asset is editable print asset " + ex.getMessage()); } return false; } private boolean isIdsTemplateAsset(Node assetNode){ try { Node metadataNode = assetNode.getNode("jcr:content/metadata"); return metadataNode.hasProperty(StringConstants.TEMPLATE_TYPE) && !StringConstants.TEMPLATE_TYPE_CATALOG.equals(metadataNode.getProperty(StringConstants.TEMPLATE_TYPE).getString()); } catch (Exception ex) { log("Exception occurred while getting indesign template asset type" + ex.getMessage()); } return false; } private boolean isRemoteAsset(Asset asset, String remoteMountPoint) { String path = asset.adaptTo(Resource.class).getPath(); if(path.startsWith(remoteMountPoint)) { return true; } return false; } private String getTemplateType(Asset asset){ try { Node metadataNode = asset.adaptTo(Node.class).getNode("jcr:content/metadata"); return metadataNode.getProperty(StringConstants.TEMPLATE_TYPE).getString(); } catch (Exception ex) { log("Exception occurred while checking whether the asset indesign template asset " + ex.getMessage()); } return "INDESIGN"; } boolean isCatalogPage(Resource resource){ Resource contentRes = resource.getChild("jcr:content"); if(contentRes != null){ Node contentNode = contentRes.adaptTo(Node.class); try { if(contentNode != null && contentNode.hasProperty(StringConstants.MASTER_FLAG) && contentNode.getProperty(StringConstants.MASTER_FLAG).getBoolean() == true){ return true; } } catch (Exception e) { return false; } } return false; } private boolean contains(String[] mimeTypes, String mimeType) { for (String item:mimeTypes) { if (item.equalsIgnoreCase(mimeType)) { return true; } } return false; } // An asset can be locked through damadmin by enabling the configuration for lock at wcm/core/content/damadmin/actions/lock // We should call isLocked function only if this configuration is enabled. // Calling isLocked leads to performance degradation. See CQ-4236465 private boolean isLockingEnabled(ResourceResolver resourceResolver) { boolean canLock = false; Resource lockedProvider = resourceResolver.getResource("/mnt/overlay/wcm/core/content/damadmin/actions/lock"); if (lockedProvider != null) { if ((boolean)lockedProvider.getValueMap().get("disabled")) { return canLock; } else { canLock = true; } } return canLock; } private boolean isLocked(ResourceResolver resourceResolver, Node node) { boolean isLocked = false; try { String lockedBy=""; final LockManager lockManager = resourceResolver.adaptTo( Session.class).getWorkspace().getLockManager(); if(node != null) { if (node.isLocked()) { isLocked=true; lockedBy = lockManager.getLock( node.getPath()).getLockOwner(); }else if (node.hasNode(JcrConstants.JCR_CONTENT)){ Node contentNode = node.getNode(JcrConstants.JCR_CONTENT); if(contentNode.isLocked()){ isLocked = true; lockedBy = lockManager.getLock(contentNode.getPath()).getLockOwner(); } } if(isLocked){ User self = resourceResolver.adaptTo(User.class); String selfId = self.getID(); isLocked = !selfId.equals(lockedBy); } return isLocked; } } catch (Exception ex) { log("Exception occurred while checking whether the node is locked: " + ex.getMessage()); } return true; } private boolean isSubAsset(final Resource resource) { if (resource == null) { return false; } return DamConstants.SUBASSETS_FOLDER.equals(ResourceUtil.getName(ResourceUtil.getParent(resource))); } private boolean isNew(Node targetNode) { Calendar lastModified = null; try { Calendar created = targetNode.getProperty("jcr:created").getDate(); if (targetNode.hasProperty("jcr:content/jcr:lastModified")) { lastModified = targetNode.getProperty("jcr:content/jcr:lastModified").getDate(); } Calendar twentyFourHoursAgo = Calendar.getInstance(); twentyFourHoursAgo.add(Calendar.DATE, -1); if (created == null || (lastModified != null && lastModified.before(created))) { created = lastModified; } return created != null && twentyFourHoursAgo.before(created); } catch (Exception ex) { log("Exception occurred while checking whether the node is new " + ex.getMessage()); } return false; } /** * Return true if the node has been created recently. * The method is used to determine if an image asset has been recently uploaded and * therefore allow the processing banner to be applied and before dam:assetState could be updated. * @param targetNode * @return true if node has been created within recent time frame. */ private boolean isRecent(Node targetNode) { Calendar lastModified = null; try { Calendar created = targetNode.getProperty("jcr:created").getDate(); if (targetNode.hasProperty("jcr:content/jcr:lastModified")) { lastModified = targetNode.getProperty("jcr:content/jcr:lastModified").getDate(); } Calendar recentTime = Calendar.getInstance(); recentTime.add(Calendar.MINUTE, -2); if (created == null || (lastModified != null && lastModified.before(created))) { created = lastModified; } return created != null && recentTime.before(created); } catch (Exception ex) { log("Exception occurred while checking whether the node is recent " + ex.getMessage()); } return false; } /** * Return true if the node has been created (including copied) recently. * The method is used to determine if a video asset has been recently uploaded or copied and * therefore allow deferred content reload to recheck in workflow status or rebuild card/list item after * the copied status has been reset. * @param targetNode * @return true if node has been created within recent time frame. */ private boolean isRecentCreated(Node targetNode) { Calendar lastModified = null; Calendar lastCopied = null; try { Calendar created = targetNode.getProperty("jcr:created").getDate(); if (targetNode.hasProperty("jcr:content/jcr:lastModified")) { lastModified = targetNode.getProperty("jcr:content/jcr:lastModified").getDate(); } if (targetNode.hasProperty("jcr:content/dam:copiedAt")) { lastCopied = targetNode.getProperty("jcr:content/dam:copiedAt").getDate(); } Calendar recentTime = Calendar.getInstance(); recentTime.add(Calendar.SECOND, -10); if (created == null || (lastCopied != null && lastCopied.after(created))) { created = lastCopied; } else if (created == null || (lastModified != null && lastModified.after(created))) { created = lastModified; } return created != null && recentTime.before(created); } catch (Exception ex) { log("Exception occurred while checking whether the node is recent " + ex.getMessage()); } return false; } private boolean isEncoded(Resource resource) { Asset asset = resource.adaptTo(Asset.class); if (asset != null) { ValueMap props = resource.getChild(JcrConstants.JCR_CONTENT) .adaptTo(ValueMap.class); String assetType = props.get(S7damConstants.PN_S7_TYPE, ""); return assetType.toLowerCase().contains(S7damConstants.S7_VIDEO.toLowerCase()); } return false; } private boolean isAsset(Resource resource) { Asset asset = resource.adaptTo(Asset.class); if (asset != null) { ValueMap props = resource.getChild(JcrConstants.JCR_CONTENT) .adaptTo(ValueMap.class); String assetType = props.get(S7damConstants.PN_S7_TYPE, ""); return assetType.equals("Asset"); } return false; } /** * Checks for any valid image or video renditions. The primary purpose of this function is to indicate that * the asset has been previously successfully processed. This function could be used to indicate encoding by * non-DM process such as ffmpeg. * @param resource Resource to check for existence of renditons * @return True if any rendition exists */ private boolean hasRendition(Resource resource) { Asset asset = resource.adaptTo(Asset.class); if (asset != null) { List rList = asset.getRenditions(); for (Rendition rendition : rList) { if (rendition != null) { String name = rendition.getName(); if (name != null && !name.equals(DamConstants.ORIGINAL_FILE) && !name.equals(S7damConstants.PN_S7_PTIFF_RENDITION_NAME)) { return true; } } } } return false; } private boolean isSnippetTemplate(Resource resource) { boolean isSnippetTemplate = false; Resource contentResource = resource.getChild(JcrConstants.JCR_CONTENT); if (resource != null && contentResource != null) { isSnippetTemplate = ResourceUtil.getValueMap(contentResource).get(DamConstants.DAM_INDESIGN_IS_SNIPPET_TEMPLATE, false); } return isSnippetTemplate; } %>