/**
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.brixcms.jcr.base.event;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import java.util.ArrayList;
import java.util.List;
/**
* ChangeLog keep tracks of events happening in a single {@link Session}. At certain points (usually when Item#save() or
* {@link Session#save()} is about to be called) ChangeLog can provide normalized list of events that have happened
* before the point.
* <p/>
* The session must add proper events to the {@link ChangeLog} using {@link #addEvent(Event)} and {@link ChangeLog} will
* make sure that the events will be normalized (i.e. redundant events will be removed, etc).
*
* @author Matej Knopp
* @see #addEvent(Event)
* @see #removeAndGetAffectedEvents(Node)
*/
public class ChangeLog {
private List<Event> events = new ArrayList<Event>();
public ChangeLog() {
}
/**
* Adds the event to the event queue.
*
* @param event
* @throws RepositoryException
*/
public void addEvent(Event event) throws RepositoryException {
final boolean blockAddingEvent[] = {false};
for (int i = 0; i < events.size(); ++i) {
Event e = events.get(i);
Event.QueueCallback callback = new Event.QueueCallback() {
public void blockAddingEvent() {
blockAddingEvent[0] = true;
}
};
events.set(i, e.onNewEvent(event, callback));
}
removeNullEvents();
if (blockAddingEvent[0] == false) {
Event transformed = event.transformBeforeAddingToQueue();
if (transformed != null) {
events.add(transformed);
}
}
}
/**
* Shrinks the queue removing null events.
*/
private void removeNullEvents() {
// remove null events
List<Event> newList = new ArrayList<Event>(events.size());
for (Event e : events) {
if (e != null) {
newList.add(e);
}
}
events = newList;
}
/**
* Removes events affected by this item (events concerning the path or any of it's children) and returns them. If path
* is<code>null</code> all events are returned.
*
* @param path
* @return
* @throws RepositoryException
*/
public List<Event> removeAndGetAffectedEvents(String path) throws RepositoryException {
List<Event> result;
if (path == null) {
result = events;
events = new ArrayList<Event>();
} else {
result = new ArrayList<Event>();
for (int i = 0; i < events.size(); ++i) {
Event e = events.get(i);
if (e.isAffected(path)) {
result.add(e);
events.set(i, null);
}
}
removeNullEvents();
}
return result;
}
}