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