/* * 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 com.sun.jini.outrigger; /** * Base class for objects that represent interest in particular entry * visibility transitions. Each <code>TransitionWatcher</code> has a * time stamp and when compared <code>TransitionWatcher</code>s with a * lower time stamp are considered less than those with a larger time * stamp. If two <code>TransitionWatcher</code> have the same time * stamp their tie breaker values are used. * <p> * Unless otherwise noted, the <code>addTemplateHandle</code> method must * be called at least once before any other method. * Some implementations of this call only support calling * <code>addTemplateHandle</code> once on any particular instance. * <p> * Unless otherwise noted, all the package protected methods * are thread safe. */ abstract class TransitionWatcher implements Comparable { /** The time stamp for this object */ final private long timestamp; /** The tie breaker for this object */ final private long tiebreaker; /** * The transitions with higher ordinals occurred * after the operation associated with this * watcher was started. Package protected * but should only be accessed by subclasses. */ final long startOrdinal; /** Next tiebreaker to use */ private static long nextTiebreaker = 0; /** Lock for nextTiebreaker */ private static Object nextTiebreakerLock = new Object(); /** * Create a new <code>TransitionWatcher</code>. * @param timestamp the value that is used * to sort <code>TransitionWatcher</code>s. * @param startOrdinal the highest ordinal associated * with operations that are considered to have occurred * before the operation associated with this watcher. */ TransitionWatcher(long timestamp, long startOrdinal) { this.timestamp = timestamp; this.startOrdinal = startOrdinal; synchronized (nextTiebreakerLock) { tiebreaker = nextTiebreaker++; } } /** * Associate a <code>TemplateHandle</code> with this object. An * implementation may support calling this method only once on * a given instance. * @param h The <code>TemplateHandle</code> associated * with this watcher. * @return <code>true</code> if the handle was succfully added, * and <code>false</code> if the watcher has already * been removed. * @throws NullPointerException if <code>h</code> is * <code>null</code> */ abstract boolean addTemplateHandle(TemplateHandle h); /** * Compares this object with another. If the other object is not a * <code>TransitionWatcher</code> a * <code>ClassCastException</code> will be thrown. The object with * the lower time stamp will be considered less than the other. If they * both have the same time stamp the object will the lower * tie breaker will be less than the other. If both have the same * tie breaker and time stamp they will be considered equal. * <p> * This method may be called before <code>addTemplateHandle</code> * is called. * * @return a negative integer, zero, or a positive integer as this * object is less than, equal to, or greater than the specified * object. * @throws ClassCastException if <code>o</code> is not * a <code>TransitionWatcher</code>. */ public int compareTo(Object o) { final TransitionWatcher other = (TransitionWatcher)o; if (timestamp < other.timestamp) return -1; if (timestamp > other.timestamp) return 1; if (tiebreaker < other.tiebreaker) return -1; if (tiebreaker > other.tiebreaker) return 1; assert o == this : "Two TransitionWatchers with the same tiebreaker"; return 0; } /* Since every TransitionWatcher has its own tie breaker * we can use the default hashCode and equals. */ /** * Get the expiration time of this object. This method may be * called before <code>addTemplateHandle</code> is called. * Assumes locking is handled by the caller. * @return The time (in milliseconds since the beginning of * the epoch) when this watcher is no longer relevant. */ abstract public long getExpiration(); /** * Remove this watcher from the system if it * has expired. Responsible * for calling the <code>remove</code> method * of the associated <code>TemplateHandle</code>. * This method can be called more than once, * though second and subsequent calls may have no effect. * @param now An estimate of the current time that must be * less than or equal to the current time. */ abstract void removeIfExpired(long now); /** * Return <code>true</code> if this watcher cares about a given * visibility transition. Assumes the transitioning entry matches * the template in the <code>TemplateHandle</code> associated with * this watcher. This method should return a value even if the * expiration time has been reached or <code>remove</code> has * been called. This call should not obtain any locks. * @param transition A <code>EntryTransition</code> that * describes the transition and what * entry is transitioning. This method * will assume that <code>transition.getHandle</code> * returns a non-null value. * @param ordinal The ordinal associated with <code>transition</code>. * @return <code>true</code> if this watcher is interested * in the indicated transition and <code>false</code> * otherwise. * @throws NullPointerException if <code>transition</code> is * <code>null</code>. */ abstract boolean isInterested(EntryTransition transition, long ordinal); /** * Process the given transition. Assumes the passed entry matches the * template in the <code>TemplateHandle</code> associated with this * watcher and that <code>isInterested</code> returned * <code>true</code>. This call may make changes to the passed * <code>EntryHandle</code> that will prevent it from being used by * other watchers. If <code>remove</code> has been called or the * expiration time of this watcher has passed, this call should have no * effect. This call may cause the watcher to be removed. * * @param transition A <code>EntryTransition</code> that * describes the transition and what * entry is transitioning. This method * will assume that <code>transition.getHandle</code> * returns a non-null value. * @param now An estimate of the current time (not the time * when the event occured). * @throws NullPointerException if <code>transition</code> is * <code>null</code>. */ abstract void process(EntryTransition transition, long now); }