001/* 002 * Copyright 2012 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.core.cocoon.source; 017 018import java.io.IOException; 019import java.io.InputStream; 020import java.util.zip.ZipEntry; 021import java.util.zip.ZipFile; 022 023import org.apache.excalibur.source.SourceNotFoundException; 024import org.apache.excalibur.source.impl.AbstractSource; 025 026/** 027 * Implementation of a Source giving access to a zip entry 028 */ 029public class ZipSource extends AbstractSource 030{ 031 private ZipFile _zipFile; 032 033 private ZipEntry _zipEntry; 034 035 /** 036 * Instanciate a ZipSource 037 * @param location the ZipSource URI, looking like : zip://path/to/file!path/to/entry 038 */ 039 public ZipSource(String location) 040 { 041 int index = location.indexOf("://"); 042 043 if (index == -1) 044 { 045 throw new IllegalArgumentException("A ZipSource URI must be like zip://path/to/file!path/to/entry"); 046 } 047 048 setScheme(location.substring(0, index)); 049 setSystemId(location.substring(index + 3)); 050 051 int fileIndex = location.indexOf('!'); 052 053 if (fileIndex < index) 054 { 055 throw new IllegalArgumentException("A ZipSource URI must be like zip://path/to/file!path/to/entry"); 056 } 057 058 String file = location.substring(index + 1, fileIndex); 059 try 060 { 061 _zipFile = new ZipFile(file); 062 } 063 catch (IOException e) 064 { 065 throw new IllegalArgumentException("Unable to open zip file", e); 066 } 067 068 String entry = location.substring(fileIndex + 1); 069 _zipEntry = _zipFile.getEntry(entry); 070 } 071 072 public boolean exists() 073 { 074 return _zipFile != null && _zipEntry != null; 075 } 076 077 @Override 078 public InputStream getInputStream() throws IOException 079 { 080 if (_zipFile == null || _zipEntry == null) 081 { 082 throw new SourceNotFoundException("ZipSource not available"); 083 } 084 085 return _zipFile.getInputStream(_zipEntry); 086 } 087 088 /** 089 * Releases resources associated with this ZipSource. 090 */ 091 public void close() 092 { 093 _zipEntry = null; 094 095 try 096 { 097 _zipFile.close(); 098 _zipFile = null; 099 } 100 catch (IOException e) 101 { 102 throw new IllegalArgumentException("Unable to close zip file"); 103 } 104 } 105}