/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.db.common.changeset; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import org.simantics.db.ChangeSet; import org.simantics.db.MetadataI; import org.simantics.db.ReadGraph; import org.simantics.db.Session; import org.simantics.db.common.procedure.adapter.TransientCacheListener; import org.simantics.db.event.ChangeEvent; import org.simantics.db.event.ChangeListener; import org.simantics.db.exception.DatabaseException; import org.simantics.db.request.Read; import org.simantics.utils.ReflectionUtils; import org.slf4j.LoggerFactory; /** * A listener added to a Session for receiving notifications for completed * write transactions. * * @see GraphChangeEvent * @see Session */ abstract public class GenericChangeListener implements ChangeListener { private final Constructor> constructor; public GenericChangeListener() { try { Class> clazz = ReflectionUtils.getSingleParameterTypeExtending(getClass()); this.constructor = clazz.getConstructor(ChangeSet.class); return; } catch (SecurityException | NoSuchMethodException e) { LoggerFactory.getLogger(getClass()).error("Could not get constructor with param {}", ChangeSet.class.getSimpleName(), e); throw new IllegalArgumentException(e); } } public final void graphChanged(ChangeEvent e) throws DatabaseException { try { if (!preEventRequest()) return; Result event = e.getGraph().syncRequest(constructor.newInstance(e.getChanges()), TransientCacheListener.instance()); onEvent(e.getGraph(), e.getMetadataI(), event); } catch (IllegalArgumentException | InstantiationException | IllegalAccessException | InvocationTargetException ex) { LoggerFactory.getLogger(getClass()).error("Could not construct new instance with {}", e.getChanges(), ex); throw new DatabaseException(ex); } } /** * Invoked before performing the event request with the received change * event and sending the result to {@link #onEvent(ReadGraph, Object)}. Can * be used to veto processing of an event. * * @return true if the event request shall be performed and the * result sent to {@link #onEvent(ReadGraph, Object)}, * false to disable any further processing of the * received db {@link ChangeEvent} * @since 1.8 */ public boolean preEventRequest() { return true; } public abstract void onEvent(ReadGraph graph, MetadataI metadata, Result event) throws DatabaseException; }