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.g2d.diagram.handler.impl;
14 import java.util.Collection;
15 import java.util.concurrent.locks.ReadWriteLock;
16 import java.util.concurrent.locks.ReentrantReadWriteLock;
18 import org.simantics.g2d.diagram.IDiagram;
19 import org.simantics.g2d.diagram.handler.LifeCycle;
20 import org.simantics.g2d.diagram.handler.TransactionContext;
21 import org.simantics.g2d.element.IElement;
22 import org.simantics.utils.datastructures.ListenerList;
23 import org.simantics.utils.datastructures.hints.IHintContext.Key;
24 import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;
27 * @author Tuukka Lehtonen
29 public class LockingTransactionContext implements TransactionContext, LifeCycle {
31 public static final LockingTransactionContext INSTANCE = new LockingTransactionContext();
33 private static final Key TRANSACTION_LISTENERS = new KeyOf(ListenerList.class, "TRANSACTION LISTENERS");
34 private static final Key TRANSACTION_LOCK = new KeyOf(ReadWriteLock.class, "TRANSACTION LOCK");
37 public void onDiagramCreated(IDiagram diagram) {
38 diagram.setHint(TRANSACTION_LISTENERS, new ListenerList<TransactionListener>(TransactionListener.class));
39 diagram.setHint(TRANSACTION_LOCK, new ReentrantReadWriteLock(true));
43 public void onDiagramLoaded(IDiagram diagram, Collection<IElement> initialElements) {
47 public void onDiagramDestroyed(IDiagram diagram) {
51 public void onDiagramDisposed(IDiagram diagram) {
52 diagram.removeHint(TRANSACTION_LISTENERS);
53 diagram.removeHint(TRANSACTION_LOCK);
57 public void addTransactionListener(IDiagram d, TransactionListener l) {
58 ListenerList<TransactionListener> ll;
60 ll = d.getHint(TRANSACTION_LISTENERS);
62 ll = new ListenerList<TransactionListener>(TransactionListener.class);
63 d.setHint(TRANSACTION_LISTENERS, ll);
70 public void removeTransactionListener(IDiagram d, TransactionListener l) {
72 ListenerList<TransactionListener> ll = d.getHint(TRANSACTION_LISTENERS);
79 void lock(ReadWriteLock lock, TransactionType type) {
82 lock.readLock().lock();
85 lock.writeLock().lock();
90 void unlock(ReadWriteLock lock, TransactionType type) {
93 lock.readLock().unlock();
96 lock.writeLock().unlock();
102 public Transaction startTransaction(IDiagram d, TransactionType type) {
103 ReadWriteLock lock = d.getHint(TRANSACTION_LOCK);
107 Transaction t = new Transaction.Impl(type);
108 ListenerList<TransactionListener> ll = d.getHint(TRANSACTION_LISTENERS);
110 for (TransactionListener l : ll.getListeners())
111 l.transactionStarted(d, t);
113 } catch (RuntimeException e) {
120 public void finishTransaction(IDiagram d, Transaction t) {
121 ReadWriteLock lock = d.getHint(TRANSACTION_LOCK);
124 ListenerList<TransactionListener> ll = d.getHint(TRANSACTION_LISTENERS);
126 for (TransactionListener l : ll.getListeners())
127 l.transactionFinished(d, t);
129 unlock(lock, t.getType());