001: /*
002:
003: Derby - Class org.apache.derby.impl.store.raw.data.InputStreamContainer
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.impl.store.raw.data.FileContainer;
025:
026: import org.apache.derby.iapi.store.raw.ContainerKey;
027:
028: import org.apache.derby.iapi.error.StandardException;
029: import org.apache.derby.iapi.store.raw.log.LogInstant;
030: import org.apache.derby.iapi.services.sanity.SanityManager;
031: import org.apache.derby.impl.store.raw.data.BaseDataFileFactory;
032:
033: import org.apache.derby.iapi.services.io.InputStreamUtil;
034: import org.apache.derby.iapi.reference.SQLState;
035:
036: import org.apache.derby.io.StorageFile;
037:
038: import java.io.InputStream;
039: import java.io.IOException;
040: import java.io.DataInputStream;
041:
042: /**
043: A class that uses a ZipEntry to be a single container file,
044: but read-only.
045:
046: */
047:
048: final class InputStreamContainer extends FileContainer {
049:
050: private StorageFile containerPath;
051:
052: /*
053: * Constructors
054: */
055:
056: InputStreamContainer(BaseDataFileFactory factory) {
057: super (factory);
058: canUpdate = false;
059: }
060:
061: final boolean openContainer(ContainerKey newIdentity)
062: throws StandardException {
063: DataInputStream dis = null;
064: try {
065: InputStream is = null;
066: containerPath = dataFactory.getContainerPath(newIdentity,
067: false);
068: try {
069: is = containerPath.getInputStream();
070: } catch (IOException ioe) {
071: // Maybe it's been stubbified.
072: containerPath = dataFactory.getContainerPath(
073: newIdentity, true);
074: try {
075: is = getInputStream();
076: } catch (IOException ioe2) {
077: containerPath = null;
078: return false;
079: }
080: }
081:
082: dis = new DataInputStream(is);
083:
084: // FileData has to be positioned just at the beginning
085: // of the first allocation page. And it is because we
086: // just opened the stream and the first allocation page
087: // is located at the beginning of the file.
088: readHeader(dis);
089:
090: return true;
091:
092: } catch (IOException ioe) {
093: throw StandardException.newException(
094: SQLState.FILE_CONTAINER_EXCEPTION, ioe, this );
095: } finally {
096: if (dis != null) {
097: try {
098: dis.close();
099: } catch (IOException ioe) {
100: }
101: }
102: }
103: } // end of openContainer
104:
105: void closeContainer() {
106: containerPath = null;
107: }
108:
109: /**
110: Write out the header information for this container. If an i/o exception
111: occurs then ...
112:
113: @see org.apache.derby.iapi.services.cache.Cacheable#clean
114: @exception StandardException Standard Cloudscape error policy
115: */
116: public final void clean(boolean forRemove) throws StandardException {
117:
118: // Nothing to do since we are inherently read-only.
119:
120: }
121:
122: /**
123: Preallocate page.
124: */
125: protected final int preAllocate(long lastPreallocPagenum,
126: int preAllocSize) {
127:
128: // Nothing to do since we are inherently read-only.
129: return 0;
130: }
131:
132: protected void truncatePages(long lastValidPagenum) {
133: // Nothing to do since we are inherently read-only.
134: return;
135: }
136:
137: /*
138: ** Container creation, opening, and closing
139: */
140:
141: /**
142: Create a new container, all references to identity must be through the
143: passed in identity, this object will no identity until after this method returns.
144: */
145: void createContainer(ContainerKey newIdentity)
146: throws StandardException {
147: // RESOLVE - probably should throw an error ...
148: }
149:
150: /**
151: Remove the container.
152: */
153: protected final void removeContainer(LogInstant instant,
154: boolean leaveStub) throws StandardException {
155: // RESOVE
156: }
157:
158: /*
159: ** Methods used solely by StoredPage
160: */
161:
162: /**
163: Read a page into the supplied array.
164:
165: <BR> MT - thread safe
166: */
167: protected final void readPage(long pageNumber, byte[] pageData)
168: throws IOException, StandardException {
169:
170: if (SanityManager.DEBUG) {
171: SanityManager.ASSERT(!getCommittedDropState());
172: }
173:
174: long pageOffset = pageNumber * pageSize;
175:
176: readPositionedPage(pageOffset, pageData);
177:
178: if (dataFactory.databaseEncrypted()
179: && pageNumber != FIRST_ALLOC_PAGE_NUMBER) {
180: decryptPage(pageData, pageSize);
181: }
182: }
183:
184: /**
185: Read the page at the positioned offset.
186: This default implementation, opens the stream and skips to the offset
187: and then reads the data into pageData.
188: */
189: protected void readPositionedPage(long pageOffset, byte[] pageData)
190: throws IOException {
191:
192: InputStream is = null;
193: try {
194: // no need to synchronize as each caller gets a new stream
195: is = getInputStream();
196:
197: InputStreamUtil.skipBytes(is, pageOffset);
198:
199: InputStreamUtil.readFully(is, pageData, 0, pageSize);
200:
201: is.close();
202: is = null;
203: } finally {
204: if (is != null) {
205: try {
206: is.close();
207: } catch (IOException ioe) {
208: }
209: }
210: }
211: }
212:
213: /**
214: Write a page from the supplied array.
215:
216: <BR> MT - thread safe
217: */
218: protected final void writePage(long pageNumber, byte[] pageData,
219: boolean syncPage) throws IOException, StandardException {
220: }
221:
222: protected final void flushAll() {
223: }
224:
225: /**
226: Get an input stream positioned at the beginning of the file
227: */
228: protected InputStream getInputStream() throws IOException {
229: return containerPath.getInputStream();
230: }
231:
232: /**
233: * Backup the container.
234: * There is no support to backup this type of containers. It may not be any
235: * real use for users because users can simply make copies of the read only
236: * database in Zip files easily using OS utilities.
237: *
238: * @exception StandardException Standard Derby error policy
239: */
240: protected void backupContainer(BaseContainerHandle handle,
241: String backupLocation) throws StandardException {
242: throw StandardException
243: .newException(SQLState.STORE_FEATURE_NOT_IMPLEMENTED);
244: }
245:
246: /**
247: * Encrypt the container. There is no support to encrypt
248: * this type of containers.
249: *
250: * @exception StandardException Standard Derby error policy
251: */
252: protected void encryptContainer(BaseContainerHandle handle,
253: String newFilePath) throws StandardException {
254: throw StandardException
255: .newException(SQLState.STORE_FEATURE_NOT_IMPLEMENTED);
256: }
257:
258: }
|