/* * Copyright 2012 Future Systems * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.krakenapps.eventstorage.engine.file; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.Date; import org.krakenapps.eventstorage.EventRecord; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public abstract class FileWriter { private Logger logger = LoggerFactory.getLogger(FileWriter.class); private int tableId; private File file; private volatile boolean modified = false; private Date lastWrite = new Date(); private Date lastFlush = new Date(); private volatile boolean closed = false; protected FileWriter(int tableId, File file) { this.tableId = tableId; this.file = file; } protected EventFileHeader getHeader(String magicString) throws IOException { EventFileHeader hdr = null; if (file.length() == 0) { hdr = new EventFileHeader((short) 1, magicString); FileOutputStream fos = null; try { fos = new FileOutputStream(file); fos.write(hdr.serialize()); } finally { if (fos != null) fos.close(); } } else { hdr = EventFileHeader.extractHeader(file); if (!hdr.magicString().equals(magicString)) throw new IllegalStateException("invalid magic string " + file.getAbsolutePath()); if (hdr.version() != 1) throw new IllegalStateException("invalid version " + file.getAbsolutePath()); } return hdr; } public int getTableId() { return tableId; } public File getFile() { return file; } public final void write(EventRecord record) throws IOException { logger.debug("kraken eventstorage: write record table [{}] file [{}]", tableId, file.getName()); if (closed) throw new IllegalStateException("closed"); modified = true; lastWrite = new Date(); doWrite(record); } protected abstract void doWrite(EventRecord record) throws IOException; public final synchronized void flush(boolean sync) throws IOException { logger.debug("kraken eventstorage: flush writer table [{}] file [{}]", tableId, file.getName()); if (closed) throw new IllegalStateException("closed"); lastFlush = new Date(); if (modified) doFlush(sync); modified = false; } protected abstract void doFlush(boolean sync) throws IOException; protected final void touch() { lastWrite = new Date(); } protected final void modify() { modified = true; } public Date getLastWriteTime() { return lastWrite; } public Date getLastFlushTime() { return lastFlush; } public boolean isClosed() { return closed; } public final void close() { if (isClosed()) return; logger.debug("kraken eventstorage: close writer table [{}] file [{}]", tableId, file.getName()); if (modified) { try { flush(true); } catch (IOException e) { logger.warn("kraken eventstorage: flush failed [{}] file [{}]", tableId, file.getName()); } } closed = true; doClose(); } protected abstract void doClose(); }