/* * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. licenses this file to you 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.wso2.siddhi.core.event; import java.io.Serializable; import java.util.Iterator; import java.util.NoSuchElementException; /** * Collection used to group and manage chunk or ComplexEvents * * @param <E> sub types of ComplexEvent such as StreamEvent and StateEvent */ public class ComplexEventChunk<E extends ComplexEvent> implements Iterator<E>, Serializable { protected E first; protected E previousToLastReturned; protected E lastReturned; protected E last; protected boolean isBatch = false; public ComplexEventChunk(boolean isBatch) { this.isBatch = isBatch; } //Only to maintain backward compatibility @Deprecated public ComplexEventChunk() { this.isBatch = true; } //Only to maintain backward compatibility @Deprecated public ComplexEventChunk(E first, E last) { this.first = first; this.last = last; this.isBatch = true; } public ComplexEventChunk(E first, E last, boolean isBatch) { this.first = first; this.last = last; this.isBatch = isBatch; } public void insertBeforeCurrent(E events) { if (lastReturned == null) { throw new IllegalStateException(); } E currentEvent = getLastEvent(events); if (previousToLastReturned != null) { previousToLastReturned.setNext(events); } else { first = events; } previousToLastReturned = currentEvent; currentEvent.setNext(lastReturned); } public void insertAfterCurrent(E streamEvents) { if (lastReturned == null) { throw new IllegalStateException(); } E currentEvent = getLastEvent(streamEvents); ComplexEvent nextEvent = lastReturned.getNext(); lastReturned.setNext(streamEvents); currentEvent.setNext(nextEvent); } public void add(E complexEvents) { if (first == null) { first = complexEvents; } else { last.setNext(complexEvents); } last = getLastEvent(complexEvents); } private E getLastEvent(E complexEvents) { E lastEvent = complexEvents; while (lastEvent != null && lastEvent.getNext() != null) { lastEvent = (E) lastEvent.getNext(); } return lastEvent; } /** * Returns <tt>true</tt> if the iteration has more elements. (In other * words, returns <tt>true</tt> if <tt>next</tt> would return an element * rather than throwing an exception.) * * @return <tt>true</tt> if the iterator has more elements. */ public boolean hasNext() { if (lastReturned != null) { return lastReturned.getNext() != null; } else if (previousToLastReturned != null) { return previousToLastReturned.getNext() != null; } else { return first != null; } } /** * Returns the next element in the iteration. * * @return the next element in the iteration. * @throws java.util.NoSuchElementException iteration has no more elements. */ public E next() { E returnEvent; if (lastReturned != null) { returnEvent = (E) lastReturned.getNext(); previousToLastReturned = lastReturned; } else if (previousToLastReturned != null) { returnEvent = (E) previousToLastReturned.getNext(); } else { returnEvent = first; } if (returnEvent == null) { throw new NoSuchElementException(); } lastReturned = returnEvent; return returnEvent; } /** * Removes from the underlying collection the last element returned by the * iterator (optional operation). This method can be called only once per * call to <tt>next</tt>. The behavior of an iterator is unspecified if * the underlying collection is modified while the iteration is in * progress in any way other than by calling this method. * * @throws UnsupportedOperationException if the <tt>remove</tt> * operation is not supported by this Iterator. * @throws IllegalStateException if the <tt>next</tt> method has not * yet been called, or the <tt>remove</tt> method has already * been called after the last call to the <tt>next</tt> * method. */ public void remove() { if (lastReturned == null) { throw new IllegalStateException(); } if (previousToLastReturned != null) { previousToLastReturned.setNext(lastReturned.getNext()); } else { first = (E) lastReturned.getNext(); if (first == null) { last = null; } } lastReturned.setNext(null); lastReturned = null; } public void detach() { if (lastReturned == null) { throw new IllegalStateException(); } if (previousToLastReturned != null) { previousToLastReturned.setNext(null); } else { clear(); } lastReturned = null; } public E detachAllBeforeCurrent() { if (lastReturned == null) { throw new IllegalStateException(); } E firstEvent = null; if (previousToLastReturned != null) { previousToLastReturned.setNext(null); firstEvent = first; first = lastReturned; previousToLastReturned = null; } return firstEvent; } public void clear() { previousToLastReturned = null; lastReturned = null; first = null; last = null; } public void reset() { previousToLastReturned = null; lastReturned = null; } public E getFirst() { return first; } public E getLast() { return last; } public E poll() { if (first != null) { E firstEvent = first; first = (E) first.getNext(); firstEvent.setNext(null); return firstEvent; } else { return null; } } public boolean isBatch() { return isBatch; } public void setBatch(boolean batch) { isBatch = batch; } @Override public String toString() { return "EventChunk{" + "first=" + first + '}'; } }