001/* 002 * (C) Copyright 2019 Nuxeo (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * pierre 018 */ 019package org.nuxeo.ecm.platform.picture.recompute; 020 021import static org.nuxeo.ecm.core.api.CoreSession.ALLOW_VERSION_WRITE; 022import static org.nuxeo.ecm.core.api.versioning.VersioningService.DISABLE_AUTO_CHECKOUT; 023import static org.nuxeo.ecm.core.bulk.BulkServiceImpl.STATUS_STREAM; 024import static org.nuxeo.ecm.core.bulk.action.SetPropertiesAction.PARAM_DISABLE_AUDIT; 025import static org.nuxeo.ecm.platform.picture.listener.PictureViewsGenerationListener.DISABLE_PICTURE_VIEWS_GENERATION_LISTENER; 026import static org.nuxeo.lib.stream.computation.AbstractComputation.INPUT_1; 027import static org.nuxeo.lib.stream.computation.AbstractComputation.OUTPUT_1; 028 029import java.io.IOException; 030import java.io.Serializable; 031import java.util.Arrays; 032import java.util.List; 033import java.util.Map; 034 035import org.apache.logging.log4j.LogManager; 036import org.apache.logging.log4j.Logger; 037import org.nuxeo.ecm.core.api.Blob; 038import org.nuxeo.ecm.core.api.CoreSession; 039import org.nuxeo.ecm.core.api.DocumentModel; 040import org.nuxeo.ecm.core.api.DocumentNotFoundException; 041import org.nuxeo.ecm.core.api.IdRef; 042import org.nuxeo.ecm.core.api.model.Property; 043import org.nuxeo.ecm.core.bulk.action.computation.AbstractBulkComputation; 044import org.nuxeo.ecm.core.bulk.message.BulkCommand; 045import org.nuxeo.ecm.core.event.Event; 046import org.nuxeo.ecm.core.event.EventService; 047import org.nuxeo.ecm.core.event.impl.DocumentEventContext; 048import org.nuxeo.ecm.platform.picture.api.adapters.PictureResourceAdapter; 049import org.nuxeo.lib.stream.computation.Topology; 050import org.nuxeo.runtime.api.Framework; 051import org.nuxeo.runtime.stream.StreamProcessorTopology; 052 053/** 054 * BAF Computation that fills picture views for the blob property described by the given xpath. 055 * 056 * @since 11.1 057 */ 058public class RecomputeViewsAction implements StreamProcessorTopology { 059 060 private static final Logger log = LogManager.getLogger(RecomputeViewsAction.class); 061 062 public static final String ACTION_NAME = "recomputeViews"; 063 064 // @since 11.1 065 public static final String ACTION_FULL_NAME = "bulk/" + ACTION_NAME; 066 067 public static final String PARAM_XPATH = "xpath"; 068 069 @Override 070 public Topology getTopology(Map<String, String> options) { 071 return Topology.builder() 072 .addComputation(RecomputeViewsComputation::new, // 073 Arrays.asList(INPUT_1 + ":" + ACTION_FULL_NAME, OUTPUT_1 + ":" + STATUS_STREAM)) 074 .build(); 075 } 076 077 public static class RecomputeViewsComputation extends AbstractBulkComputation { 078 079 public static final String PICTURE_VIEWS_GENERATION_DONE_EVENT = "pictureViewsGenerationDone"; 080 081 protected String xpath; 082 083 public RecomputeViewsComputation() { 084 super(ACTION_FULL_NAME); 085 } 086 087 @Override 088 public void startBucket(String bucketKey) { 089 BulkCommand command = getCurrentCommand(); 090 xpath = command.getParam(PARAM_XPATH); 091 } 092 093 @Override 094 protected void compute(CoreSession session, List<String> ids, Map<String, Serializable> properties) { 095 log.debug("Compute action: {} for doc ids: {}", ACTION_NAME, ids); 096 for (String docId : ids) { 097 098 if (!session.exists(new IdRef(docId))) { 099 log.debug("Doc id doesn't exist: {}", docId); 100 continue; 101 } 102 103 DocumentModel workingDocument = session.getDocument(new IdRef(docId)); 104 Property fileProp = workingDocument.getProperty(xpath); 105 Blob blob = (Blob) fileProp.getValue(); 106 if (blob == null) { 107 // do nothing 108 log.debug("No blob for doc: {}", workingDocument); 109 continue; 110 } 111 112 String title = workingDocument.getTitle(); 113 try { 114 PictureResourceAdapter picture = workingDocument.getAdapter(PictureResourceAdapter.class); 115 log.debug("Fill picture views for doc: {}", workingDocument); 116 picture.fillPictureViews(blob, blob.getFilename(), title, null); 117 } catch (DocumentNotFoundException e) { 118 // a parent of the document may have been deleted. 119 continue; 120 } catch (IOException e) { 121 throw new RuntimeException(e); 122 } 123 124 if (workingDocument.isVersion()) { 125 workingDocument.putContextData(ALLOW_VERSION_WRITE, Boolean.TRUE); 126 } 127 workingDocument.putContextData("disableNotificationService", Boolean.TRUE); 128 workingDocument.putContextData(PARAM_DISABLE_AUDIT, Boolean.TRUE); 129 workingDocument.putContextData(DISABLE_AUTO_CHECKOUT, Boolean.TRUE); 130 workingDocument.putContextData(DISABLE_PICTURE_VIEWS_GENERATION_LISTENER, Boolean.TRUE); 131 session.saveDocument(workingDocument); 132 133 DocumentEventContext ctx = new DocumentEventContext(session, session.getPrincipal(), workingDocument); 134 Event event = ctx.newEvent(PICTURE_VIEWS_GENERATION_DONE_EVENT); 135 Framework.getService(EventService.class).fireEvent(event); 136 } 137 } 138 } 139}