blob: 7d0e867396f9dbd7eeee4ccce92bdac37486f2f7 [file] [log] [blame]
/*
Derby - Class org.apache.derby.iapi.services.monitor.DerbyObservable
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF 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.apache.derby.iapi.services.monitor;
import java.util.Vector;
/**
* <p>
* Created to provide the Observable behavior which Derby has depended
* on since Java 1.2 but which as deprecated in JDK 9 build 118. A DerbyObservable
* is an object whose state changes are being tracked.
* </p>
*/
public class DerbyObservable
{
//////////////////////////////////////////////////////////////////////
//
// STATE
//
//////////////////////////////////////////////////////////////////////
private boolean _hasChanged = false;
private Vector<DerbyObserver> _observers;
//////////////////////////////////////////////////////////////////////
//
// CONSTRUCTORS
//
//////////////////////////////////////////////////////////////////////
/** No-arg constructor */
public DerbyObservable() { _observers = new Vector<DerbyObserver>(); }
//////////////////////////////////////////////////////////////////////
//
// PUBLIC BEHAVIOR
//
//////////////////////////////////////////////////////////////////////
/**
* Add another observer who wants to be told about changes to this object.
*
* @param observer The object which wants to be notified when this object changes
*
* @throw IllegalArgumentException If the argument is bad (e.g., null)
*/
public void addObserver(DerbyObserver observer)
{
if (observer == null) { throw new IllegalArgumentException("Null arguments not allowed."); }
if (!_observers.contains(observer)) { _observers.addElement(observer); }
}
/**
* Return the number of observers who are watching this object.
*
* @return The number of watchers
*/
public int countObservers() { return _observers.size(); }
/**
* Remove a specific observer from the list of watchers. Null is ignored.
*
* @param observer The observer to remove.
*/
public void deleteObserver(DerbyObserver observer) { _observers.removeElement(observer); }
/**
* This method is equivalent to notifyObservers(null);
*/
public void notifyObservers() { notifyObservers(null); }
/**
* If this object has changed, then notify all observers. Pass
* them this object and the extraInfo. This object is then marked
* as unchanged again.
*
* @param extraInfo Extra information to be passed to the observer's callback method.
*/
public void notifyObservers(Object extraInfo)
{
// Shield the observers from further changes to the list of watchers
DerbyObserver[] cachedObservers;
synchronized (this)
{
if (!_hasChanged) { return; }
cachedObservers = new DerbyObserver[_observers.size()];
_observers.toArray(cachedObservers);
_hasChanged = false;
}
int lastIndex = cachedObservers.length - 1;
for (int idx = lastIndex; idx >= 0; idx--)
{
cachedObservers[idx].update(this, extraInfo);
}
}
//////////////////////////////////////////////////////////////////////
//
// PROTECTED BEHAVIOR TO BE CALLED BY SUBCLASSES
//
//////////////////////////////////////////////////////////////////////
/**
* When the object state changes, the object calls this method
* in order to flag that fact. After this method has been called,
* then the notifyObservers() will wake up the observers which are
* watching this object.
*/
protected void setChanged() { _hasChanged = true; }
}