001: /*
002:
003: Derby - Class org.apache.derby.impl.store.raw.data.StreamFileContainerHandle
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.impl.store.raw.data;
023:
024: import org.apache.derby.iapi.services.locks.Lockable;
025: import org.apache.derby.iapi.services.sanity.SanityManager;
026: import org.apache.derby.iapi.error.StandardException;
027: import org.apache.derby.iapi.store.raw.StreamContainerHandle;
028: import org.apache.derby.iapi.store.raw.ContainerKey;
029: import org.apache.derby.iapi.store.raw.xact.RawTransaction;
030:
031: import org.apache.derby.iapi.types.DataValueDescriptor;
032:
033: import org.apache.derby.impl.store.raw.data.DropOnCommit;
034:
035: import org.apache.derby.catalog.UUID;
036:
037: import java.util.Observable;
038: import java.util.Observer;
039: import java.util.Properties;
040:
041: /**
042: A handle to an open stream container, implememts StreamContainerHandle.
043: <P>
044: This class is an Observer to observe RawTransactions
045:
046: <BR> MT - Mutable - Immutable identity - Thread Aware
047: */
048:
049: final class StreamFileContainerHandle implements StreamContainerHandle,
050: Observer {
051:
052: /*
053: ** Fields
054: */
055:
056: /**
057: Raw Store identifier
058: <BR> MT - Immutable
059: */
060: private final UUID rawStoreId;
061:
062: /**
063: Container identifier
064: <BR> MT - Immutable
065: */
066: protected final ContainerKey identity;
067:
068: /**
069: Is this StreamContainerHandle active.
070:
071: <BR> MT - Mutable : scoped
072: */
073: protected boolean active;
074:
075: /**
076: The actual container we are accessing. Only valid when active is true.
077:
078: <BR> MT - Mutable : scoped
079: */
080: protected StreamFileContainer container;
081:
082: /**
083: our transaction. Only valid when active is true.
084:
085: <BR> MT - Mutable : scoped
086: */
087: protected RawTransaction xact;
088:
089: /**
090: Whether this container should be held open across commit.
091: Only valid when active is true.
092:
093: <BR> MT - Mutable : scoped
094: */
095: private boolean hold;
096:
097: /*
098: ** Constructor
099: */
100: public StreamFileContainerHandle(UUID rawStoreId,
101: RawTransaction xact, ContainerKey identity, boolean hold) {
102: this .identity = identity;
103: this .xact = xact;
104: this .rawStoreId = rawStoreId;
105: this .hold = hold;
106: }
107:
108: public StreamFileContainerHandle(UUID rawStoreId,
109: RawTransaction xact, StreamFileContainer container,
110: boolean hold) {
111:
112: this .identity = container.getIdentity();
113: this .xact = xact;
114: this .rawStoreId = rawStoreId;
115: this .hold = hold;
116:
117: this .container = container;
118:
119: // we are inactive until useContainer is called.
120: }
121:
122: /*
123: ** Methods from StreamContainerHandle
124: */
125:
126: /**
127: * Request the system properties associated with a container.
128: * @see StreamContainerHandle#getContainerProperties
129: * @param prop Property list to fill in.
130: *
131: * @exception StandardException Standard exception policy.
132: **/
133: public void getContainerProperties(Properties prop)
134: throws StandardException {
135:
136: container.getContainerProperties(prop);
137: return;
138: }
139:
140: /**
141: * fetch a row from the container.
142: *
143: * @exception StandardException Standard exception policy.
144: **/
145: public boolean fetchNext(DataValueDescriptor[] row)
146: throws StandardException {
147:
148: return container.fetchNext(row);
149: }
150:
151: /**
152: @see StreamContainerHandle#close
153:
154: @exception StandardException Standard exception policy.
155: */
156: public void close() {
157:
158: if (xact == null) {
159:
160: // Probably be closed explicitly by a client, after closing
161: // automatically after an abort.
162: if (SanityManager.DEBUG)
163: SanityManager.ASSERT(!active);
164:
165: return;
166: }
167:
168: active = false;
169:
170: // let go of the container
171: container.close();
172: container = null;
173:
174: // and remove ourseleves from this transaction
175: xact.deleteObserver(this );
176:
177: xact = null;
178: }
179:
180: /**
181: remove the stream container
182:
183: @exception StandardException Standard Cloudscape error policy
184: @see StreamContainerHandle#removeContainer
185: */
186: public void removeContainer() throws StandardException {
187: container.removeContainer();
188: }
189:
190: /**
191: get the container key for the stream container
192: */
193: public ContainerKey getId() {
194: return identity;
195: }
196:
197: /*
198: ** Methods of Observer
199: */
200:
201: /**
202: Called when the transaction is about to complete.
203:
204: @see Observer#update
205: */
206: public void update(Observable obj, Object arg) {
207: if (SanityManager.DEBUG) {
208: if (arg == null)
209: SanityManager.THROWASSERT("still on observr list "
210: + this );
211: }
212:
213: // already been removed from the list
214: if (xact == null) {
215:
216: return;
217: }
218:
219: if (SanityManager.DEBUG) {
220: // just check reference equality
221:
222: if (obj != xact)
223: SanityManager
224: .THROWASSERT("Observable passed to update is incorrect expected "
225: + xact + " got " + obj);
226: }
227:
228: // close on a commit, abort or drop of this container.
229: if (arg.equals(RawTransaction.COMMIT)
230: || arg.equals(RawTransaction.ABORT)
231: || arg.equals(identity)) {
232: // close the container
233: close();
234: return;
235:
236: }
237:
238: if (arg.equals(RawTransaction.SAVEPOINT_ROLLBACK)) {
239:
240: // remain open
241: return;
242: }
243: }
244:
245: /*
246: ** Implementation specific methods, these are public so that they can be called
247: ** in other packages that are specific implementations of Data, ie.
248: ** a directory at the level
249: **
250: ** com.ibm.db2j.impl.Database.Storage.RawStore.Data.*
251: */
252:
253: /**
254: Attach me to a container. If this method returns false then
255: I cannot be used anymore, and any reference to me must be discarded.
256:
257: @exception StandardException Standard Cloudscape error policy
258: */
259: public boolean useContainer() throws StandardException {
260:
261: if (SanityManager.DEBUG) {
262: SanityManager.ASSERT(!active);
263: SanityManager.ASSERT(container != null);
264: }
265:
266: // always set forUpdate to false
267: if (!container.use(this )) {
268: container = null;
269: return false;
270: }
271:
272: active = true;
273:
274: // watch transaction and close ourseleves just before it completes.
275: if (!hold) {
276: xact.addObserver(this );
277: xact.addObserver(new DropOnCommit(identity, true));
278: }
279:
280: return true;
281: }
282:
283: /**
284: Return the RawTransaction this object was opened in.
285: */
286: public final RawTransaction getTransaction() {
287:
288: if (SanityManager.DEBUG) {
289: SanityManager.ASSERT(xact != null);
290: }
291:
292: return xact;
293: }
294:
295: /*
296: ** Implementation specific methods for myself and my sub-classes
297: */
298: public String toString() {
299: if (SanityManager.DEBUG) {
300: String str = new String();
301: str += "StreamContainerHandle:(" + identity.toString()
302: + ")";
303: return (str);
304: } else {
305: return (super.toString());
306: }
307: }
308: }
|