diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/business/BusinessObjectFactory.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/business/BusinessObjectFactory.java index 966240e03b13c22c83afa056ffa11c7142a4486e..209e514577fa40d7b5ec171fec47c3a768f97100 100644 --- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/business/BusinessObjectFactory.java +++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/business/BusinessObjectFactory.java @@ -32,10 +32,10 @@ public class BusinessObjectFactory extends AbstractPluginBusinessObjectFactory private final IDAOFactory daoFactory; private final IPhosphoNetXDAOFactory specificDAOFactory; - public BusinessObjectFactory(IDAOFactory daoFactory, IPhosphoNetXDAOFactory specificDAOFactory) + public BusinessObjectFactory(IDAOFactory daoFactory, IPhosphoNetXDAOFactory specificDAOFactory, String typeOfCaching) { this.daoFactory = daoFactory; - this.specificDAOFactory = specificDAOFactory; + this.specificDAOFactory = new DAOFactoryWithCache(specificDAOFactory, typeOfCaching); } public ISampleLister createSampleLister(Session session) diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/business/DAOFactoryWithCache.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/business/DAOFactoryWithCache.java new file mode 100644 index 0000000000000000000000000000000000000000..a70b57d86dad42fbec3abd41aa17423cf28dfcfe --- /dev/null +++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/business/DAOFactoryWithCache.java @@ -0,0 +1,344 @@ +/* + * Copyright 2010 ETH Zuerich, CISD + * + * 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 ch.systemsx.cisd.openbis.plugin.phosphonetx.server.business; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +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.Map; + +import net.lemnik.eodsql.DataSet; + +import org.apache.commons.io.IOUtils; + +import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel; +import ch.systemsx.cisd.openbis.plugin.phosphonetx.server.dataaccess.IPhosphoNetXDAOFactory; +import ch.systemsx.cisd.openbis.plugin.phosphonetx.server.dataaccess.IProteinQueryDAO; +import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.dto.IdentifiedPeptide; +import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.dto.IdentifiedProtein; +import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.dto.ProbabilityFDRMapping; +import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.dto.ProteinReference; +import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.dto.ProteinReferenceWithPeptideSequence; +import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.dto.ProteinReferenceWithProbability; +import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.dto.ProteinReferenceWithProbabilityAndPeptide; +import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.dto.SampleAbundance; +import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.dto.Sequence; + +/** + * + * + * @author Franz-Josef Elmer + */ +class DAOFactoryWithCache implements IPhosphoNetXDAOFactory +{ + private IProteinQueryDAO proteinQueryDAO; + + private static final class ProteinQueryDAO implements IProteinQueryDAO + { + private static final class ListBasedDataSet<T> extends ArrayList<T> implements DataSet<T> + { + private static final long serialVersionUID = 1L; + + ListBasedDataSet(DataSet<T> dataSet) + { + try + { + for (T row : dataSet) + { + add(row); + } + } finally + { + dataSet.close(); + } + } + + public void close() + { + } + + public void disconnect() + { + } + + public boolean isConnected() + { + return false; + } + } + + private static interface IDataSetLoader<T> + { + public DataSet<T> load(String experimentPermID); + } + + private static final class FileBasedDataSetLoader<T> implements IDataSetLoader<T> + { + private final File store; + + FileBasedDataSetLoader(File store) + { + this.store = store; + store.mkdirs(); + } + + void save(String experimentPermID, DataSet<T> dataSet) + { + File file = new File(store, experimentPermID); + ObjectOutputStream outputStream = null; + try + { + outputStream = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file), 1024*1024)); + outputStream.writeObject(dataSet); + } catch (IOException ex) + { + throw CheckedExceptionTunnel.wrapIfNecessary(ex); + } finally + { + IOUtils.closeQuietly(outputStream); + } + } + + @SuppressWarnings("unchecked") + public DataSet<T> load(String experimentPermID) + { + File file = new File(store, experimentPermID); + if (file.exists() == false) + { + return null; + } + ObjectInputStream inputStream = null; + try + { + inputStream = new ObjectInputStream(new BufferedInputStream(new FileInputStream(file), 1024*1024)); + return (DataSet<T>) inputStream.readObject(); + } catch (Exception ex) + { + throw CheckedExceptionTunnel.wrapIfNecessary(ex); + } finally + { + IOUtils.closeQuietly(inputStream); + } + } + + } + + private static final class ResultSetCache<T> + { + private enum CachingType { MEMORY, FILE_SYSTEM } + + private final String name; + private final IDataSetLoader<T> dataSetLoader; + private final Map<String, DataSet<T>> cache; + private final FileBasedDataSetLoader<T> fileBasedDataSetLoader; + private final CachingType cachingType; + + ResultSetCache(String name, String typeOfCaching, IDataSetLoader<T> dataSetLoader) + { + this.name = name; + cachingType = resolve(typeOfCaching); + fileBasedDataSetLoader = new FileBasedDataSetLoader<T>(new File(name)); + this.dataSetLoader = dataSetLoader; + cache = new HashMap<String, DataSet<T>>(); + } + + private CachingType resolve(String typeOfCaching) + { + CachingType[] values = CachingType.values(); + for (CachingType type : values) + { + if (type.toString().equalsIgnoreCase(typeOfCaching)) + { + return type; + } + } + return null; + } + + DataSet<T> getDataSet(String experimentPermID) + { + long time = System.currentTimeMillis(); + DataSet<T> dataSet; + if (cachingType == CachingType.MEMORY) + { + dataSet = cache.get(experimentPermID); + if (dataSet == null) + { + DataSet<T> resultSet = dataSetLoader.load(experimentPermID); + dataSet = new ListBasedDataSet<T>(resultSet); + cache.put(experimentPermID, dataSet); + } + } else if (cachingType == CachingType.FILE_SYSTEM) + { + dataSet = fileBasedDataSetLoader.load(experimentPermID); + if (dataSet == null) + { + DataSet<T> resultSet = dataSetLoader.load(experimentPermID); + dataSet = new ListBasedDataSet<T>(resultSet); + fileBasedDataSetLoader.save(experimentPermID, dataSet); + } + } else + { + dataSet = new ListBasedDataSet<T>(dataSetLoader.load(experimentPermID)); + } + System.out.println(System.currentTimeMillis() - time + "msec for " + name); + return dataSet; + } + } + + private final IProteinQueryDAO dao; + + private final ResultSetCache<ProteinReferenceWithProbability> listProteinsByExperimentCache; + + private final ResultSetCache<ProteinReferenceWithPeptideSequence> listProteinsWithSequencesByExperimentCache; + + private final ResultSetCache<ProteinReferenceWithPeptideSequence> listProteinsWithPeptidesByExperiment; + + ProteinQueryDAO(final IProteinQueryDAO dao, String typeOfCaching) + { + System.getProperties().list(System.out); + this.dao = dao; + listProteinsByExperimentCache = + new ResultSetCache<ProteinReferenceWithProbability>("listProteinsByExperiment", typeOfCaching, + new IDataSetLoader<ProteinReferenceWithProbability>() + { + + public DataSet<ProteinReferenceWithProbability> load( + String experimentPermID) + { + return dao.listProteinsByExperiment(experimentPermID); + } + }); + listProteinsWithSequencesByExperimentCache = + new ResultSetCache<ProteinReferenceWithPeptideSequence>( + "listProteinsWithSequencesByExperiment", typeOfCaching, + new IDataSetLoader<ProteinReferenceWithPeptideSequence>() + { + + public DataSet<ProteinReferenceWithPeptideSequence> load( + String experimentPermID) + { + return dao + .listProteinsWithSequencesByExperiment(experimentPermID); + } + }); + listProteinsWithPeptidesByExperiment = + new ResultSetCache<ProteinReferenceWithPeptideSequence>( + "listProteinsWithPeptidesByExperiment", typeOfCaching, + new IDataSetLoader<ProteinReferenceWithPeptideSequence>() + { + + public DataSet<ProteinReferenceWithPeptideSequence> load( + String experimentPermID) + { + return dao + .listProteinsWithPeptidesByExperiment(experimentPermID); + } + }); + } + + public void close() + { + dao.close(); + } + + public DataSet<ProbabilityFDRMapping> getProbabilityFDRMapping(long dataSetID) + { + return dao.getProbabilityFDRMapping(dataSetID); + } + + public boolean isClosed() + { + return dao.isClosed(); + } + + public DataSet<String> listAbundanceRelatedSamplePermIDsByExperiment(String experimentPermID) + { + return dao.listAbundanceRelatedSamplePermIDsByExperiment(experimentPermID); + } + + public DataSet<IdentifiedPeptide> listIdentifiedPeptidesByProtein(long proteinID) + { + return dao.listIdentifiedPeptidesByProtein(proteinID); + } + + public DataSet<ProteinReferenceWithProbability> listProteinsByExperiment( + String experimentPermID) + { + return listProteinsByExperimentCache.getDataSet(experimentPermID); + } + + public DataSet<IdentifiedProtein> listProteinsByProteinReferenceAndExperiment( + String experimentPermID, long proteinReferenceID) + { + return dao.listProteinsByProteinReferenceAndExperiment(experimentPermID, + proteinReferenceID); + } + + public DataSet<Sequence> listProteinSequencesByProteinReference(long proteinReferenceID) + { + return dao.listProteinSequencesByProteinReference(proteinReferenceID); + } + + public DataSet<ProteinReferenceWithPeptideSequence> listProteinsWithPeptidesByExperiment( + String experimentPermID) + { + return listProteinsWithPeptidesByExperiment.getDataSet(experimentPermID); + } + + public DataSet<ProteinReferenceWithProbabilityAndPeptide> listProteinsWithProbabilityAndPeptidesByExperiment( + String experimentPermID) + { + return dao.listProteinsWithProbabilityAndPeptidesByExperiment(experimentPermID); + } + + public DataSet<ProteinReferenceWithPeptideSequence> listProteinsWithSequencesByExperiment( + String experimentPermID) + { + return listProteinsWithSequencesByExperimentCache.getDataSet(experimentPermID); + } + + public DataSet<SampleAbundance> listSampleAbundanceByProtein(String experimentPermID, + long proteinReferenceID) + { + return dao.listSampleAbundanceByProtein(experimentPermID, proteinReferenceID); + } + + public ProteinReference tryToGetProteinReference(long proteinReferenceID) + { + return dao.tryToGetProteinReference(proteinReferenceID); + } + } + + DAOFactoryWithCache(IPhosphoNetXDAOFactory daoFactory, String typeOfCaching) + { + proteinQueryDAO = new ProteinQueryDAO(daoFactory.getProteinQueryDAO(), typeOfCaching); + } + + public IProteinQueryDAO getProteinQueryDAO() + { + return proteinQueryDAO; + } + +} diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/AbstractDTOWithID.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/AbstractDTOWithID.java index d03bce6c5660652bd79fd513504937b7e95d9379..3b2f27f86666fdf00de9df5f588304276be5132a 100644 --- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/AbstractDTOWithID.java +++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/AbstractDTOWithID.java @@ -16,6 +16,8 @@ package ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.dto; +import java.io.Serializable; + import net.lemnik.eodsql.ResultColumn; /** @@ -23,8 +25,10 @@ import net.lemnik.eodsql.ResultColumn; * * @author Franz-Josef Elmer */ -abstract class AbstractDTOWithID +abstract class AbstractDTOWithID implements Serializable { + private static final long serialVersionUID = 1L; + @ResultColumn("id") private long id; diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/ProteinReference.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/ProteinReference.java index 94fabdad50a57672a14c5395431bed410174d5ab..025b01b77f85b2e458227a4cf06c8d5ea000477a 100644 --- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/ProteinReference.java +++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/ProteinReference.java @@ -16,6 +16,8 @@ package ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.dto; +import java.io.Serializable; + import net.lemnik.eodsql.ResultColumn; /** @@ -23,8 +25,10 @@ import net.lemnik.eodsql.ResultColumn; * * @author Franz-Josef Elmer */ -public class ProteinReference extends AbstractDTOWithID +public class ProteinReference extends AbstractDTOWithID implements Serializable { + private static final long serialVersionUID = 1L; + @ResultColumn("accession_number") private String accessionNumber; diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/ProteinReferenceWithPeptideSequence.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/ProteinReferenceWithPeptideSequence.java index 8188a1425d1262fd92f367593b3fbc2682230483..6a914d7fca99ea14d1026dd2a176add9243e71c3 100644 --- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/ProteinReferenceWithPeptideSequence.java +++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/ProteinReferenceWithPeptideSequence.java @@ -16,6 +16,8 @@ package ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.dto; +import java.io.Serializable; + import net.lemnik.eodsql.ResultColumn; /** @@ -23,8 +25,10 @@ import net.lemnik.eodsql.ResultColumn; * * @author Franz-Josef Elmer */ -public class ProteinReferenceWithPeptideSequence +public class ProteinReferenceWithPeptideSequence implements Serializable { + private static final long serialVersionUID = 1L; + @ResultColumn("prre_id") private long id; diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/ProteinReferenceWithProbability.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/ProteinReferenceWithProbability.java index 73bd90d1b340ec940bcfd2a6fb0f947d057764c3..922b24a770c1a49ae3316ccfd8bb9372b9c4228a 100644 --- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/ProteinReferenceWithProbability.java +++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/ProteinReferenceWithProbability.java @@ -16,6 +16,8 @@ package ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.dto; +import java.io.Serializable; + import net.lemnik.eodsql.ResultColumn; /** @@ -23,8 +25,10 @@ import net.lemnik.eodsql.ResultColumn; * * @author Franz-Josef Elmer */ -public class ProteinReferenceWithProbability extends ProteinReference +public class ProteinReferenceWithProbability extends ProteinReference implements Serializable { + private static final long serialVersionUID = 1L; + @ResultColumn("data_set_id") private long dataSetID; diff --git a/rtd_phosphonetx/source/java/phosphonetx-applicationContext.xml b/rtd_phosphonetx/source/java/phosphonetx-applicationContext.xml index 7b2ea654b2df3fd08b7f7d376a5eee644de4539f..f07dc588873328398414440d98db65fc985e08c6 100644 --- a/rtd_phosphonetx/source/java/phosphonetx-applicationContext.xml +++ b/rtd_phosphonetx/source/java/phosphonetx-applicationContext.xml @@ -38,6 +38,7 @@ class="ch.systemsx.cisd.openbis.plugin.phosphonetx.server.business.BusinessObjectFactory"> <constructor-arg ref="dao-factory"/> <constructor-arg ref="phosphonetx-dao-factory"/> + <constructor-arg value="${type-of-caching}"/> </bean> <!--