001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020 package org.apache.directory.shared.ldap.cursor; 021 022 023 /** 024 * A basic ClosureMonitor that simply uses a boolean for state and a cause 025 * exception. 026 * 027 * Note that we consciously chose not to synchronize close() operations with 028 * checks to see if the monitor state is closed because it costs to 029 * synchronize and it's OK for the Cursor not to stop immediately when close() 030 * is called. 031 * 032 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 033 * @version $Rev$, $Date$ 034 */ 035 public class DefaultClosureMonitor implements ClosureMonitor 036 { 037 /** Tells if the monitor is closed or not */ 038 private boolean closed; 039 040 /** If we get an exception, the cause is stored in this variable */ 041 private Exception cause; 042 043 044 /** 045 * {@inheritDoc} 046 */ 047 public final void close() 048 { 049 // state check needed to "try" not to overwrite exception (lack of 050 // synchronization may still allow overwriting but who cares that much 051 if ( ! closed ) 052 { 053 // not going to sync because who cares if it takes a little longer 054 // to stop but we need to set cause before toggling closed state 055 // or else check for closure can throw null cause 056 cause = new CursorClosedException(); 057 closed = true; 058 } 059 } 060 061 062 /** 063 * {@inheritDoc} 064 */ 065 public final void close( final String cause ) 066 { 067 // state check needed to "try" not to overwrite exception (lack of 068 // synchronization may still allow overwriting but who cares that much 069 if ( ! closed ) 070 { 071 // not going to sync because who cares if it takes a little longer 072 // to stop but we need to set cause before toggling closed state 073 // or else check for closure can throw null cause 074 this.cause = new CursorClosedException( cause ); 075 closed = true; 076 } 077 } 078 079 080 /** 081 * {@inheritDoc} 082 */ 083 public final void close( final Exception cause ) 084 { 085 // state check needed to "try" not to overwrite exception (lack of 086 // synchronization may still allow overwriting but who cares that much 087 if ( ! closed ) 088 { 089 // not going to sync because who cares if it takes a little longer 090 // to stop but we need to set cause before toggling closed state 091 // or else check for closure can throw null cause 092 this.cause = cause; 093 closed = true; 094 } 095 } 096 097 098 /** 099 * {@inheritDoc} 100 */ 101 public final Exception getCause() 102 { 103 return cause; 104 } 105 106 107 /** 108 * {@inheritDoc} 109 */ 110 public final boolean isClosed() 111 { 112 return closed; 113 } 114 115 116 /** 117 * {@inheritDoc} 118 */ 119 public void checkNotClosed() throws Exception 120 { 121 // lack of synchronization may cause pass but eventually it will work 122 if ( closed ) 123 { 124 throw cause; 125 } 126 } 127 }