/*
*
* Copyright SHMsoft, Inc.
*
* 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.freeeed.search.web.dao.cases;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.log4j.Logger;
import org.freeeed.search.web.model.Case;
/**
*
* CaseDao implementation, using file system as storage.
*
* @author ilazarov.
*
*/
public class FSCaseDao implements CaseDao {
private static final String CASES_FILE = "work/c.dat";
private static final Logger logger = Logger.getLogger(FSCaseDao.class);
private Map<Long, Case> casesCache;
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
private AtomicLong idGenerator;
public void init() {
lock.writeLock().lock();
try {
logger.info("Init FS Cases DAO...");
casesCache = new HashMap<Long, Case>();
loadCases();
initIDGenerator();
} finally {
lock.writeLock().unlock();
}
}
@Override
public List<Case> listCases() {
List<Case> result = new ArrayList<Case>();
lock.readLock().lock();
try {
result.addAll(casesCache.values());
} finally {
lock.readLock().unlock();
}
return result;
}
@Override
public Case findCase(long id) {
lock.readLock().lock();
try {
return casesCache.get(id);
} finally {
lock.readLock().unlock();
}
}
@Override
public void saveCase(Case c) {
lock.writeLock().lock();
try {
if (c.getId() == null) {
c.setId(idGenerator.incrementAndGet());
}
casesCache.put(c.getId(), c);
storeCases();
} finally {
lock.writeLock().unlock();
}
}
@Override
public void deleteCase(long id) {
lock.writeLock().lock();
try {
casesCache.remove(id);
storeCases();
} finally {
lock.writeLock().unlock();
}
}
private void storeCases() {
FileOutputStream fos = null;
ObjectOutputStream oos = null;
try {
File dir = new File(CASES_FILE);
File parent = dir.getParentFile();
if (!parent.exists()) {
parent.mkdirs();
}
fos = new FileOutputStream(dir);
oos = new ObjectOutputStream(fos);
oos.writeObject(casesCache);
oos.close();
fos.close();
} catch (Exception e) {
logger.error("Problem storing cases from file system!", e);
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
logger.error("Problem closing", e);
}
}
if (oos != null) {
try {
oos.close();
} catch (IOException e) {
logger.error("Problem closing", e);
}
}
}
}
private void loadCases() {
FileInputStream fis = null;
ObjectInputStream ois = null;
logger.info("Preparing to open the file " + new File(CASES_FILE).getAbsolutePath());
try {
fis = new FileInputStream(CASES_FILE);
ois = new ObjectInputStream(fis);
@SuppressWarnings("unchecked")
Map<Long, Case> data = (Map<Long, Case>) ois.readObject();
if (data != null) {
casesCache = data;
}
} catch (Exception e) {
logger.error("Problem loading cases from file system!", e);
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
logger.error("Problem closing", e);
}
}
if (ois != null) {
try {
ois.close();
} catch (IOException e) {
logger.error("Problem closing", e);
}
}
}
}
private void initIDGenerator() {
long max = 0;
for (Case c : casesCache.values()) {
if (c.getId() > max) {
max = c.getId();
}
}
idGenerator = new AtomicLong(max);
}
}