001/* 002 * Licensed to DuraSpace under one or more contributor license agreements. 003 * See the NOTICE file distributed with this work for additional information 004 * regarding copyright ownership. 005 * 006 * DuraSpace licenses this file to you under the Apache License, 007 * Version 2.0 (the "License"); you may not use this file except in 008 * compliance with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.fcrepo.kernel.modeshape.observer.eventmappings; 019 020import static org.fcrepo.kernel.modeshape.utils.UncheckedFunction.uncheck; 021import static org.fcrepo.kernel.modeshape.observer.FedoraEventImpl.from; 022import static org.fcrepo.kernel.modeshape.observer.FedoraEventImpl.getResourceTypes; 023import static org.slf4j.LoggerFactory.getLogger; 024import static java.util.stream.Collectors.groupingBy; 025import static java.util.stream.Collectors.toSet; 026import static java.util.stream.Stream.empty; 027import static java.util.stream.Stream.of; 028 029import java.util.List; 030import java.util.function.Function; 031import java.util.stream.Stream; 032 033import javax.jcr.observation.Event; 034 035import org.fcrepo.kernel.api.observer.FedoraEvent; 036import org.fcrepo.kernel.modeshape.observer.FedoraEventImpl; 037 038import org.slf4j.Logger; 039 040/** 041 * Maps all JCR {@link Event}s concerning one JCR node to one {@link FedoraEvent}. Adds the types of those JCR events 042 * together to calculate the final type of the emitted FedoraEvent. 043 * 044 * @author ajs6f 045 * @author acoburn 046 * @since Feb 27, 2014 047 */ 048public class AllNodeEventsOneEvent implements InternalExternalEventMapper { 049 050 private final static Logger LOGGER = getLogger(AllNodeEventsOneEvent.class); 051 052 /** 053 * Extracts an identifier from a JCR {@link Event} by building an id from nodepath and user to collapse multiple 054 * events from repository mutations 055 */ 056 private static final Function<Event, String> EXTRACT_NODE_ID = uncheck(ev -> { 057 final FedoraEvent event = from(ev); 058 final String id = event.getPath() + "-" + event.getUserID(); 059 LOGGER.debug("Sorting an event by identifier: {}", id); 060 return id; 061 }); 062 063 @Override 064 public Stream<FedoraEvent> apply(final Stream<Event> events) { 065 // first, index all the events by path-userID and then flatMap over that list of values 066 // each of which returns either a singleton Stream or an empty Stream. The final result 067 // will be a concatenated Stream of FedoraEvent objects. 068 return events.collect(groupingBy(EXTRACT_NODE_ID)).entrySet().stream().flatMap(entry -> { 069 final List<Event> evts = entry.getValue(); 070 if (!evts.isEmpty()) { 071 // build a FedoraEvent from the first JCR Event 072 final FedoraEvent fedoraEvent = from(evts.get(0)); 073 evts.stream().skip(1).forEach(evt -> { 074 // add types to the FedoraEvent from the subsequent JCR Events 075 fedoraEvent.getTypes().add(FedoraEventImpl.valueOf(evt.getType())); 076 fedoraEvent.getResourceTypes().addAll(getResourceTypes(evt).collect(toSet())); 077 }); 078 return of(fedoraEvent); 079 } 080 return empty(); 081 }); 082 } 083}