1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.db.common.changeset;
14 import java.lang.reflect.Constructor;
15 import java.lang.reflect.InvocationTargetException;
17 import org.simantics.db.ChangeSet;
18 import org.simantics.db.MetadataI;
19 import org.simantics.db.ReadGraph;
20 import org.simantics.db.Session;
21 import org.simantics.db.common.procedure.adapter.TransientCacheListener;
22 import org.simantics.db.event.ChangeEvent;
23 import org.simantics.db.event.ChangeListener;
24 import org.simantics.db.exception.DatabaseException;
25 import org.simantics.db.request.Read;
26 import org.simantics.utils.ReflectionUtils;
27 import org.slf4j.LoggerFactory;
30 * A listener added to a Session for receiving notifications for completed
33 * @see GraphChangeEvent
36 abstract public class GenericChangeListener<Request, Result> implements ChangeListener {
38 private final Constructor<Read<Result>> constructor;
40 public GenericChangeListener() {
43 Class<Read<Result>> clazz = ReflectionUtils.getSingleParameterTypeExtending(getClass());
44 this.constructor = clazz.getConstructor(ChangeSet.class);
46 } catch (SecurityException | NoSuchMethodException e) {
47 LoggerFactory.getLogger(getClass()).error("Could not get constructor with param {}", ChangeSet.class.getSimpleName(), e);
48 throw new IllegalArgumentException(e);
52 public final void graphChanged(ChangeEvent e) throws DatabaseException {
55 if (!preEventRequest())
58 Result event = e.getGraph().syncRequest(constructor.newInstance(e.getChanges()), TransientCacheListener.<Result>instance());
59 onEvent(e.getGraph(), e.getMetadataI(), event);
60 } catch (IllegalArgumentException | InstantiationException | IllegalAccessException | InvocationTargetException ex) {
61 LoggerFactory.getLogger(getClass()).error("Could not construct new instance with {}", e.getChanges(), ex);
62 throw new DatabaseException(ex);
68 * Invoked before performing the event request with the received change
69 * event and sending the result to {@link #onEvent(ReadGraph, Object)}. Can
70 * be used to veto processing of an event.
72 * @return <code>true</code> if the event request shall be performed and the
73 * result sent to {@link #onEvent(ReadGraph, Object)},
74 * <code>false</code> to disable any further processing of the
75 * received db {@link ChangeEvent}
78 public boolean preEventRequest() {
82 public abstract void onEvent(ReadGraph graph, MetadataI metadata, Result event) throws DatabaseException;