Java tutorial
/** * Copyright (C) 2007 Sly Technologies, Inc. This library is free software; you * can redistribute it and/or modify it under the terms of the GNU Lesser * General Public License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. This * library is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.slytechs.file.snoop; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.ByteOrder; import org.apache.commons.logging.Log; import org.jnetstream.capture.FileFormatException; import org.jnetstream.capture.FileMode; import org.jnetstream.capture.FormatType; import org.jnetstream.capture.PacketIterator; import org.jnetstream.capture.file.HeaderReader; import org.jnetstream.capture.file.RawIterator; import org.jnetstream.capture.file.Record; import org.jnetstream.capture.file.RecordFilterTarget; import org.jnetstream.capture.file.RecordIterator; import org.jnetstream.capture.file.snoop.SnoopBlockRecord; import org.jnetstream.capture.file.snoop.SnoopDLT; import org.jnetstream.capture.file.snoop.SnoopFile; import org.jnetstream.capture.file.snoop.SnoopPacket; import org.jnetstream.capture.file.snoop.SnoopRecord; import org.jnetstream.filter.Filter; import org.jnetstream.packet.ProtocolFilterTarget; import org.jnetstream.protocol.Protocol; import com.slytechs.capture.DefaultCaptureDevice; import com.slytechs.capture.file.AbstractFile; import com.slytechs.capture.file.RawIteratorBuilder; import com.slytechs.capture.file.editor.FileEditor; import com.slytechs.capture.file.editor.FileEditorImpl; import com.slytechs.utils.collection.IOSkippableIterator; /** * @author Mark Bednarczyk * @author Sly Technologies, Inc. */ public class SnoopFileCapture extends AbstractFile<SnoopPacket, SnoopRecord, SnoopBlockRecord> implements SnoopFile { private static final Log logger = SnoopFile.logger; /** * */ private static HeaderReader headerReader = SnoopFile.headerReader; /** * Creates a new file by creating an empty file, then writting a block header * into it and then closes the created file. The file has to be reopened as a * normal file if you need access to its contents. * * @param file * file to create * @param mode * TODO * @param filter * TODO * @param order * byte ordering for all the headers within the file * @throws FileNotFoundException * unable to find parent directory inorder to create a new file * @throws IOException * any IO errors * @throws FileFormatException */ public static SnoopFile createFile(final File file, final FileMode mode, Filter<ProtocolFilterTarget> filter) throws FileNotFoundException, IOException, FileFormatException { if (logger.isDebugEnabled()) { logger.debug(file.getName() + ", mode=" + mode + (filter == null ? "" : filter)); } // Create empty file? if (file.createNewFile() == false) { throw new FileNotFoundException("Unable to create new file [" + file.getName() + "]"); } SnoopFile capture = new SnoopFileCapture(FileMode.ReadWrite); /* * Open up in READONLY MODE since file is empty anyway, nothing to override, * we will append memory cache based segments and flush them out. */ final FileEditor editor = new FileEditorImpl(file, FileMode.ReadWrite, headerReader, ByteOrder.BIG_ENDIAN, filter, (RawIteratorBuilder) capture); SnoopBlockRecordImpl.createBlock(capture, editor); editor.close(); // Flush and close capture = new SnoopFileCapture(file, mode, null); return capture; } /** * */ private FileMode mode; /** * @param f * @param mode * @param filter * @throws FileFormatException * @throws IOException */ public SnoopFileCapture(final File f, final FileMode mode, Filter<ProtocolFilterTarget> filter) throws FileFormatException, IOException { super(logger, filter, headerReader); this.mode = mode; if (logger.isDebugEnabled()) { logger.debug(f.getName() + ", mode=" + mode + (filter == null ? "" : filter)); } this.openFile(f, this.filter); } private SnoopFileCapture(final FileMode mode) { super(logger, null, headerReader); this.mode = mode; } /* * (non-Javadoc) * * @see org.jnetstream.capture.FileCapture#getBlockIterator() */ public IOSkippableIterator<SnoopBlockRecord> getBlockIterator() throws IOException { final SnoopBlockRecord parentsBlock = this.block; return new IOSkippableIterator<SnoopBlockRecord>() { private SnoopBlockRecord block = null; public boolean hasNext() throws IOException { return this.block == null; } public SnoopBlockRecord next() throws IOException { this.block = parentsBlock; return this.block; } public void remove() throws IOException { throw new UnsupportedOperationException( "Pcap file format does not allow block record to be removed"); } public void skip() throws IOException { this.block = parentsBlock; } }; } protected PacketIterator<SnoopPacket> createPacketIterator(final RawIterator raw) throws IOException { return new SnoopPacketIterator(this.editor, this.block, raw, getCaptureDevice()); } /* * (non-Javadoc) * * @see org.jnetstream.capture.file.snoop.SnoopFile#getRecordIterator() */ public RecordIterator<SnoopRecord> getRecordIterator() throws IOException { return new SnoopRecordIterator(this, this.editor, this.block, getRawIterator()); } private void openFile(final File file, Filter<ProtocolFilterTarget> filter) throws IOException, FileFormatException { if (file.canRead() == false) { throw new FileNotFoundException( "File [" + file.getName() + "] is not readable, can not open in [" + mode.toString() + "]mode"); } if (mode.isAppend() || mode.isContent() || mode.isStructure()) { if (file.canWrite() == false) { throw new FileNotFoundException( "File [" + file.getName() + "] is readonly, can not open in read-write mode"); } } this.editor = new FileEditorImpl(file, this.mode, headerReader, ByteOrder.BIG_ENDIAN, filter, this); try { this.block = new SnoopBlockRecordImpl(this, this.editor); } finally { if (this.block == null) { /* * Make sure to close the editor in case any errors occured, otherwise * we could keep the file open until the VM terminates */ this.editor.close(); } } final Protocol dlt = SnoopDLT.asConst(block.getLinktype()); setCaptureDevice(new DefaultCaptureDevice(dlt)); if (logger.isDebugEnabled()) { logger.debug("edito=" + editor.getFlexRegion().toString()); } } /* * (non-Javadoc) * * @see org.jnetstream.capture.FileCapture#order() */ public ByteOrder order() { return ByteOrder.BIG_ENDIAN; } /* * (non-Javadoc) * * @see org.jnetstream.capture.FileCapture#getFileType() */ public FormatType getFormatType() { return FormatType.Snoop; } /* * (non-Javadoc) * * @see org.jnetstream.capture.FileCapture#getRecordIterator(org.jnetstream.filter.Filter) */ public RecordIterator<? extends Record> getRecordIterator(Filter<RecordFilterTarget> filter) throws IOException { return new SnoopRecordIterator(this, editor, block, getRawIterator(filter)); } public RawIterator createRawIterator(Filter<RecordFilterTarget> filter) throws IOException { return new SnoopRawIterator(editor.getFlexRegion(), editor, this, filter); } }