blob: 94d832be2986b49f3bd7c45157ade0f98e0cca7e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008-2011 Chair for Applied Software Engineering,
* Technische Universitaet Muenchen.
* 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:
******************************************************************************/
package org.eclipse.emf.emfstore.client.model.changeTracking.notification.recording;
import java.util.Date;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.emfstore.client.model.changeTracking.notification.NotificationInfo;
import org.eclipse.emf.emfstore.common.model.util.ModelUtil;
/**
* A Notification recorder is meant to generate a NotificationRecording. To create the recording just repeatedly call
* record() with incoming EMF notifications.
*
* @author chodnick
*/
public class NotificationRecorder {
private boolean recordingComplete;
private NotificationRecording recording;
/**
* Records a new EMF Notification.
*
* @param n the notification to record
*/
public void record(Notification n) {
if (recording == null || isRecordingComplete()) {
newRecording();
}
recording.record(n);
updateRecordingComplete();
}
/**
* Returns a completed notification recording, may throw IllegalStateException in case the recording is requested
* while recording still takes place, i.e. the EMF notification chain is not completed yet.
*
* @return a completed notification recording if one is ready
*/
public NotificationRecording getRecording() {
if (isRecordingComplete()) {
return recording;
} else {
throw new IllegalStateException("trying to get a recording, that is not finished yet");
}
}
/**
* Tries to stop an ongoing recording, useful only in context of delete operations, in which multiple EMF
* notification chains are recorded as a single sequence.
*/
public void stopRecording() {
// empty delete might actually happen
if (recording == null /* || recording.empty() */) {
throw new IllegalStateException("trying to close an empty recording");
}
if (lastNotificationHasFollowUps()) {
throw new IllegalStateException(
"trying to close a recording, even though its last notification has followups");
}
recordingComplete = true;
}
private void updateRecordingComplete() {
recordingComplete = !(recording == null || recording.empty()
|| recording.getHint().needsManualStopOfRecording() || lastNotificationHasFollowUps());
}
private boolean lastNotificationHasFollowUps() {
if (recording == null) {
return false;
}
return notificationHasFollowUps(recording.getLastRecorded());
}
private boolean notificationHasFollowUps(NotificationInfo n) {
if (n == null) {
return false;
}
return n.hasNext();
}
/**
* Starts a new recording.
*/
public void newRecording() {
newRecording(NotificationRecordingHint.DEFAULT);
}
/**
* Starts a new recording.
*
* @param aHint the hint to use when creating the new recording.
*/
public void newRecording(NotificationRecordingHint aHint) {
if (recording != null && !isRecordingComplete()) {
String message = "trying to create new notification chain, even though there is an uncompleted chain present";
ModelUtil.logException(message, new IllegalStateException(message));
}
recording = new NotificationRecording();
recording.setHint(aHint);
recording.setDate(new Date());
recordingComplete = false;
}
/**
* @return true if current recording is completed and closed, false otherwise
*/
public boolean isRecordingComplete() {
return recordingComplete;
}
}