--- /dev/null
+/*\r
+\r
+ Derby - Class org.apache.derby.impl.store.raw.data.InputStreamContainer\r
+\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to you under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.impl.store.raw.data;\r
+\r
+import org.apache.derby.impl.store.raw.data.FileContainer;\r
+\r
+import org.apache.derby.iapi.store.raw.ContainerKey;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+import org.apache.derby.iapi.store.raw.log.LogInstant;\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+import org.apache.derby.impl.store.raw.data.BaseDataFileFactory;\r
+\r
+import org.apache.derby.iapi.services.io.InputStreamUtil;\r
+import org.apache.derby.iapi.reference.SQLState;\r
+\r
+import org.apache.derby.io.StorageFile;\r
+\r
+import java.io.InputStream;\r
+import java.io.IOException;\r
+import java.io.DataInputStream;\r
+\r
+/**\r
+ A class that uses a ZipEntry to be a single container file,\r
+ but read-only.\r
+\r
+*/\r
+\r
+final class InputStreamContainer extends FileContainer {\r
+\r
+ private StorageFile containerPath;\r
+ \r
+ /*\r
+ * Constructors\r
+ */\r
+\r
+ InputStreamContainer(BaseDataFileFactory factory) {\r
+ super(factory);\r
+ canUpdate = false;\r
+ }\r
+\r
+ final boolean openContainer(ContainerKey newIdentity) throws StandardException {\r
+ DataInputStream dis = null;\r
+ try\r
+ {\r
+ InputStream is = null;\r
+ containerPath = dataFactory.getContainerPath(newIdentity, false);\r
+ try\r
+ {\r
+ is = containerPath.getInputStream();\r
+ }\r
+ catch (IOException ioe)\r
+ {\r
+ // Maybe it's been stubbified.\r
+ containerPath = dataFactory.getContainerPath(newIdentity, true);\r
+ try\r
+ {\r
+ is = getInputStream();\r
+ }\r
+ catch (IOException ioe2)\r
+ {\r
+ containerPath = null;\r
+ return false;\r
+ }\r
+ }\r
+\r
+ dis = new DataInputStream(is);\r
+ \r
+ // FileData has to be positioned just at the beginning \r
+ // of the first allocation page. And it is because we\r
+ // just opened the stream and the first allocation page\r
+ // is located at the beginning of the file.\r
+ readHeader(getEmbryonicPage(dis));\r
+\r
+ return true;\r
+\r
+ } catch (IOException ioe) {\r
+ throw StandardException.\r
+ newException(SQLState.FILE_CONTAINER_EXCEPTION, ioe, this);\r
+ } finally {\r
+ if (dis != null) {\r
+ try {\r
+ dis.close();\r
+ } catch (IOException ioe) {}\r
+ }\r
+ }\r
+ } // end of openContainer\r
+\r
+ void closeContainer()\r
+ {\r
+ containerPath = null;\r
+ }\r
+\r
+ /**\r
+ Write out the header information for this container. If an i/o exception\r
+ occurs then ...\r
+\r
+ @see org.apache.derby.iapi.services.cache.Cacheable#clean\r
+ @exception StandardException Standard Derby error policy\r
+ */\r
+ public final void clean(boolean forRemove) throws StandardException {\r
+\r
+ // Nothing to do since we are inherently read-only.\r
+\r
+ }\r
+\r
+ /**\r
+ Preallocate page. \r
+ */\r
+ protected final int preAllocate(long lastPreallocPagenum, int preAllocSize) {\r
+\r
+ // Nothing to do since we are inherently read-only.\r
+ return 0;\r
+ }\r
+\r
+ protected void truncatePages(long lastValidPagenum)\r
+ {\r
+ // Nothing to do since we are inherently read-only.\r
+ return;\r
+ }\r
+ \r
+\r
+ /*\r
+ ** Container creation, opening, and closing\r
+ */\r
+\r
+ /**\r
+ Create a new container, all references to identity must be through the\r
+ passed in identity, this object will no identity until after this method returns.\r
+ */\r
+ void createContainer(ContainerKey newIdentity) throws StandardException {\r
+ // RESOLVE - probably should throw an error ...\r
+ }\r
+\r
+\r
+\r
+ /**\r
+ Remove the container.\r
+ */\r
+ protected final void removeContainer(LogInstant instant, boolean leaveStub) throws StandardException \r
+ {\r
+ // RESOVE\r
+ }\r
+\r
+ /*\r
+ ** Methods used solely by StoredPage\r
+ */\r
+\r
+ /**\r
+ Read a page into the supplied array.\r
+\r
+ <BR> MT - thread safe\r
+ */\r
+ protected final void readPage(long pageNumber, byte[] pageData) \r
+ throws IOException, StandardException\r
+ {\r
+\r
+ if (SanityManager.DEBUG) {\r
+ SanityManager.ASSERT(!getCommittedDropState());\r
+ }\r
+\r
+ long pageOffset = pageNumber * pageSize;\r
+\r
+ readPositionedPage(pageOffset, pageData);\r
+\r
+ if (dataFactory.databaseEncrypted() && \r
+ pageNumber != FIRST_ALLOC_PAGE_NUMBER)\r
+ {\r
+ decryptPage(pageData, pageSize);\r
+ }\r
+ }\r
+\r
+ /**\r
+ Read the page at the positioned offset.\r
+ This default implementation, opens the stream and skips to the offset\r
+ and then reads the data into pageData.\r
+ */\r
+ protected void readPositionedPage(long pageOffset, byte[] pageData) throws IOException {\r
+\r
+\r
+ InputStream is = null;\r
+ try {\r
+ // no need to synchronize as each caller gets a new stream\r
+ is = getInputStream();\r
+\r
+ InputStreamUtil.skipBytes(is, pageOffset);\r
+\r
+ InputStreamUtil.readFully(is, pageData, 0, pageSize);\r
+\r
+ is.close();\r
+ is = null;\r
+ } finally {\r
+ if (is != null) {\r
+ try {is.close();} catch (IOException ioe) {}\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ Write a page from the supplied array.\r
+\r
+ <BR> MT - thread safe\r
+ */\r
+ protected final void writePage(long pageNumber, byte[] pageData, boolean syncPage)\r
+ throws IOException, StandardException {\r
+ }\r
+\r
+ protected final void flushAll() {\r
+ }\r
+\r
+ /**\r
+ Get an input stream positioned at the beginning of the file\r
+ */\r
+ protected InputStream getInputStream() throws IOException\r
+ {\r
+ return containerPath.getInputStream();\r
+ }\r
+\r
+ \r
+ /**\r
+ * Backup the container.\r
+ * There is no support to backup this type of containers. It may not be any\r
+ * real use for users because users can simply make copies of the read only \r
+ * database in Zip files easily using OS utilities.\r
+ * \r
+ * @exception StandardException Standard Derby error policy \r
+ */\r
+ protected void backupContainer(BaseContainerHandle handle, String backupLocation)\r
+ throws StandardException\r
+ {\r
+ throw StandardException.newException(\r
+ SQLState.STORE_FEATURE_NOT_IMPLEMENTED);\r
+ }\r
+\r
+\r
+ /**\r
+ * Encrypt the container. There is no support to encrypt \r
+ * this type of containers. \r
+ * \r
+ * @exception StandardException Standard Derby error policy \r
+ */\r
+ protected void encryptContainer(BaseContainerHandle handle, \r
+ String newFilePath)\r
+ throws StandardException\r
+ {\r
+ throw StandardException.newException(\r
+ SQLState.STORE_FEATURE_NOT_IMPLEMENTED);\r
+ }\r
+\r
+}\r