mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-08 17:45:24 +02:00
[163592] first cut at transaction boundary for model operations
This commit is contained in:
parent
5fccbf7ad8
commit
8151b81c20
1 changed files with 139 additions and 0 deletions
|
@ -0,0 +1,139 @@
|
||||||
|
/********************************************************************************
|
||||||
|
* Copyright (c) 2006 IBM Corporation. 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
|
||||||
|
*
|
||||||
|
* Initial Contributors:
|
||||||
|
* David Dykstal (IBM) - initial API and implementation
|
||||||
|
********************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.rse.core.model;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.rse.core.RSECorePlugin;
|
||||||
|
import org.eclipse.rse.logging.Logger;
|
||||||
|
import org.eclipse.rse.persistence.IRSEPersistenceManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a transaction boundary for RSE model operations. All operations that
|
||||||
|
* modify model objects should be done within an RSEModelOperation. These operations
|
||||||
|
* may be nested. Changes made to the model will be persisted when the outermost
|
||||||
|
* operation of a particular thread is exited.
|
||||||
|
* <p>
|
||||||
|
* The usage idiom is to create an anonymous subclass of this class just prior to
|
||||||
|
* use, overriding the {@link #execute()} method, and then invoke the {@link #run()} method.
|
||||||
|
* <pre>
|
||||||
|
* RSEModelOperation m = new RSEModelOperation() {
|
||||||
|
* public void execute() {
|
||||||
|
* ... do work here ...
|
||||||
|
* }
|
||||||
|
* };
|
||||||
|
* m.run();
|
||||||
|
* </pre>
|
||||||
|
* <p>
|
||||||
|
* under development - provisional
|
||||||
|
* @since RSE 2.0
|
||||||
|
*/
|
||||||
|
public abstract class RSEModelOperation {
|
||||||
|
|
||||||
|
private static Map threads = new HashMap();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the current thread to see if there is a model transaction in progress.
|
||||||
|
* Should be used inside model objects prior to a change to a persistent property.
|
||||||
|
*/
|
||||||
|
public static void check() {
|
||||||
|
if (getDepth() == 0) {
|
||||||
|
Logger logger = RSECorePlugin.getDefault().getLogger();
|
||||||
|
logger.logInfo("not inside transaction"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the depth of the nesting for transactions in the current thread
|
||||||
|
*/
|
||||||
|
private static int getDepth() {
|
||||||
|
Thread myThread = Thread.currentThread();
|
||||||
|
if (threads.get(myThread) == null) {
|
||||||
|
threads.put(myThread, new Integer(0));
|
||||||
|
}
|
||||||
|
int depth = ((Integer) threads.get(myThread)).intValue();
|
||||||
|
return depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begins a transaction.
|
||||||
|
*/
|
||||||
|
private static void beginTransaction() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ends a transaction. Schedules all changed profiles for save.
|
||||||
|
*/
|
||||||
|
private static void endTransaction() {
|
||||||
|
ISystemRegistry registry = RSECorePlugin.getDefault().getSystemRegistry();
|
||||||
|
ISystemProfileManager profileManager = registry.getSystemProfileManager();
|
||||||
|
IRSEPersistenceManager persistenceManager = RSECorePlugin.getDefault().getPersistenceManager();
|
||||||
|
persistenceManager.commit(profileManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enters a new nested level of operation.
|
||||||
|
*/
|
||||||
|
private static void enterLevel() {
|
||||||
|
int depth = getDepth();
|
||||||
|
try {
|
||||||
|
if (depth == 0) {
|
||||||
|
beginTransaction();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
Thread myThread = Thread.currentThread();
|
||||||
|
threads.put(myThread, new Integer(depth + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Leaves the current nesting level. If leaving the outermost nesting level then
|
||||||
|
* ends the transaction.
|
||||||
|
*/
|
||||||
|
private static void leaveLevel() {
|
||||||
|
int depth = getDepth();
|
||||||
|
try {
|
||||||
|
if (depth == 1) {
|
||||||
|
endTransaction();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
Thread myThread = Thread.currentThread();
|
||||||
|
threads.put(myThread, new Integer(depth - 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new operation scoped to the current thread.
|
||||||
|
*/
|
||||||
|
public RSEModelOperation() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform the work of this operation. This is where the work of modifying several model
|
||||||
|
* properties or objects can be done.
|
||||||
|
*/
|
||||||
|
public abstract void execute();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs this operation. This will cause the {@link #execute()} method to be invoked inside
|
||||||
|
* a transaction boundary.
|
||||||
|
*/
|
||||||
|
public void run() {
|
||||||
|
enterLevel();
|
||||||
|
try {
|
||||||
|
execute();
|
||||||
|
} finally {
|
||||||
|
leaveLevel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue