package org.jacorb.notification; /* * JacORB - a free Java ORB * * Copyright (C) 1997-2014 Gerald Brose / The JacORB Team. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.TreeSet; import org.omg.CosNotification.EventType; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; /** * Utility class that manages Sets of EventTypes. EventTypes can be added and removed. * this class will calculate recalculate its internal Set and notify its listeners * if its state has changed. * * @author Alphonse Bendt */ public abstract class EventTypeSet { private final static EventTypeWrapper[] EVENT_TYPE_WRAPPER_TEMPLATE = new EventTypeWrapper[0]; private Set eventTypeSet_ = new TreeSet(); private final ReadWriteLock readWriteLock_ = new ReentrantReadWriteLock(); private final Object arrayViewLock_ = new Object(); private EventType[] arrayView_ = null; private boolean eventTypeSetModified_ = true; protected static final EventType[] EMPTY_EVENT_TYPE = new EventType[0]; //////////////////////////////////////// public void changeSet(EventType[] added, EventType[] removed) { final List _addedList = new ArrayList(); final List _removedList = new ArrayList(); boolean _modified = false; try { readWriteLock_.writeLock().lock(); Set _modifiedSet = new TreeSet(eventTypeSet_); for (int x = 0; x < removed.length; ++x) { EventTypeWrapper event = new EventTypeWrapper(removed[x]); _modifiedSet.remove(event); } for (int x = 0; x < added.length; ++x) { EventTypeWrapper event = new EventTypeWrapper(added[x]); _modifiedSet.add(event); } Iterator _i = _modifiedSet.iterator(); while (_i.hasNext()) { Object _eventType = _i.next(); if (!eventTypeSet_.contains(_eventType)) { _addedList.add(_eventType); _modified = true; } } _i = eventTypeSet_.iterator(); while (_i.hasNext()) { Object _eventType = _i.next(); if (!_modifiedSet.contains(_eventType)) { _removedList.add(_eventType); _modified = true; } } if (_modified) { synchronized (arrayViewLock_) { eventTypeSet_ = _modifiedSet; eventTypeSetModified_ = true; } } } finally { readWriteLock_.writeLock().unlock(); } if (_modified) { fireSetChanged(_addedList, _removedList); } } private void fireSetChanged(List added, List removed) { EventType[] _addedArray = new EventType[added.size()]; for (int x = 0; x < _addedArray.length; ++x) { _addedArray[x] = ((EventTypeWrapper) added.get(x)).getEventType(); } EventType[] _removedArray = new EventType[removed.size()]; for (int x = 0; x < _removedArray.length; ++x) { _removedArray[x] = ((EventTypeWrapper) removed.get(x)).getEventType(); } actionSetChanged(_addedArray, _removedArray); } protected abstract void actionSetChanged(EventType[] added, EventType[] removed); protected EventType[] getAllTypes() { try { readWriteLock_.readLock().lock(); updateArrayView(); return arrayView_; } finally { readWriteLock_.readLock().unlock(); } } private void updateArrayView() { synchronized (arrayViewLock_) { if (eventTypeSetModified_) { EventTypeWrapper[] _allWrapped = (EventTypeWrapper[]) eventTypeSet_ .toArray(EVENT_TYPE_WRAPPER_TEMPLATE); EventType[] _all = new EventType[_allWrapped.length]; for (int x = 0; x < _allWrapped.length; ++x) { _all[x] = _allWrapped[x].getEventType(); } eventTypeSetModified_ = false; arrayView_ = _all; } } } }