/* * Copyright (c) 2010 The Jackson Laboratory * * This is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This software 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software. If not, see <http://www.gnu.org/licenses/>. */ package org.jax.maanova.project; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentLinkedQueue; import org.jax.maanova.madata.MicroarrayExperiment; import org.jax.r.jriutilities.RInterface; import org.jax.r.jriutilities.RObject; /** * This class is the root access point for all of the R data that * a J/maanova project cares about * @author <A HREF="mailto:keith.sheppard@jax.org">Keith Sheppard</A> */ public class MaanovaDataModel { private final RInterface rInterface; private final ConcurrentLinkedQueue<MaanovaDataModelListener> listenerList = new ConcurrentLinkedQueue<MaanovaDataModelListener>(); private final Map<String, MicroarrayExperiment> identifierToMicroarrayExperimentMap = Collections.synchronizedMap(new HashMap<String, MicroarrayExperiment>()); /** * Constructor * @param rInterface * the R interface to use */ public MaanovaDataModel(RInterface rInterface) { this.rInterface = rInterface; this.updateAll(); } /** * Returns a mapping from the R identifier (AKA the accessor string) * of a microarray data object and the java type that represents that * R object * @return * the mapping */ public Map<String, MicroarrayExperiment> getMicroarrayExperimentMap() { return this.identifierToMicroarrayExperimentMap; } /** * A convenience function that uses {@link #getMicroarrayExperimentMap()} * to construct an array of microarray data objects * @return * the array */ public MicroarrayExperiment[] getMicroarrays() { synchronized(this.identifierToMicroarrayExperimentMap) { MicroarrayExperiment[] microarrays = new MicroarrayExperiment[this.identifierToMicroarrayExperimentMap.size()]; return this.identifierToMicroarrayExperimentMap.values().toArray(microarrays); } } /** * Calling this function refreshes all of the data structures and makes * sure that the java types match up with the R types */ public void updateAll() { List<RObject> rMicroarrays = MicroarrayExperiment.getAllMicroarrayExperimentRObjects( this.rInterface); // add new microarrays List<MicroarrayExperiment> addedMicroarrays = new ArrayList<MicroarrayExperiment>(); for(RObject rMicroarrayObj: rMicroarrays) { MicroarrayExperiment matchingMircroarray = this.identifierToMicroarrayExperimentMap.get( rMicroarrayObj.getAccessorExpressionString()); if(matchingMircroarray == null) { matchingMircroarray = new MicroarrayExperiment( this.rInterface, rMicroarrayObj.getAccessorExpressionString()); this.identifierToMicroarrayExperimentMap.put( rMicroarrayObj.getAccessorExpressionString(), matchingMircroarray); addedMicroarrays.add(matchingMircroarray); } } // remove any missing microarrays List<MicroarrayExperiment> removedMicroarrays = new ArrayList<MicroarrayExperiment>(); synchronized(this.identifierToMicroarrayExperimentMap) { Iterator<MicroarrayExperiment> microarrayEntryIter = this.identifierToMicroarrayExperimentMap.values().iterator(); while(microarrayEntryIter.hasNext()) { MicroarrayExperiment currMicroarray = microarrayEntryIter.next(); boolean foundMatch = false; for(RObject currMicroarrayRObject: rMicroarrays) { if(currMicroarray.getAccessorExpressionString().equals( currMicroarrayRObject.getAccessorExpressionString())) { foundMatch = true; } } if(!foundMatch) { removedMicroarrays.add(currMicroarray); microarrayEntryIter.remove(); } } } // handle notification for(MicroarrayExperiment currAddedMicroarrays: addedMicroarrays) { this.fireMicroarrayExperimentAdded(currAddedMicroarrays); } for(MicroarrayExperiment currRemovedMicroarrays: removedMicroarrays) { this.fireMicroarrayExperimentRemoved(currRemovedMicroarrays); } } /** * Add the given listener to the listener list * @param maanovaDataModelListener * the listener to add */ public void addMaanovaDataModelListener( MaanovaDataModelListener maanovaDataModelListener) { this.listenerList.add(maanovaDataModelListener); } /** * Remove the given listener from the listener list * @param maanovaDataModelListener * the listener to remove */ public void removeMaanovaDataModelListener( MaanovaDataModelListener maanovaDataModelListener) { this.listenerList.remove(maanovaDataModelListener); } /** * Notifies all of the listeners that microarray data has been added * @param addedMicroarrayExperiment * the data that was added */ private void fireMicroarrayExperimentAdded(MicroarrayExperiment addedMicroarrayExperiment) { Iterator<MaanovaDataModelListener> listenerIter = this.listenerList.iterator(); while(listenerIter.hasNext()) { listenerIter.next().microarrayExperimentAdded(this, addedMicroarrayExperiment); } } /** * Notifies all of the listeners that microarray data has been removed * @param removedMicroarrayExperiment * the data that was removed */ private void fireMicroarrayExperimentRemoved(MicroarrayExperiment removedMicroarrayExperiment) { Iterator<MaanovaDataModelListener> listenerIter = this.listenerList.iterator(); while(listenerIter.hasNext()) { listenerIter.next().microarrayExperimentRemoved(this, removedMicroarrayExperiment); } } }