/* ========================
* JSynoptic : a free Synoptic editor
* ========================
*
* Project Info: http://jsynoptic.sourceforge.net/index.html
*
* This program 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 program 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
* program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* (C) Copyright 2001-2004, by :
* Corporate:
* EADS Astrium SAS
* EADS CRC
* Individual:
* Claude Cazenave
*
* $Id: FileDataSourceProvider.java,v 1.4 2007/06/05 14:17:45 ogor Exp $
*
* Changes
* -------
* 11 jan. 2005 : Initial public release (CC);
*
*/
package simtools.data;
import java.io.File;
import java.io.IOException;
import javax.swing.filechooser.FileFilter;
import simtools.data.DataSource;
import simtools.data.DataSourceCollection;
import simtools.data.DataSourcePool;
import simtools.data.DataSourceProvider;
import simtools.data.DuplicateIdException;
import simtools.data.EmptyDataSourcePool;
import simtools.data.async.TimeStampedDataSourceCollection.InvalidFormatException;
import simtools.util.FileSerializer;
/**
* @author zxpletran007
* A data source provider that restores a collection from a file
*/
public abstract class FileDataSourceProvider implements DataSourceProvider {
protected boolean chooseAgain;
protected String marker;
protected FileFilter filter;
protected static final int YES_OPTION = 0;
protected static final int NO_OPTION = 1;
protected static final int CANCEL_OPTION = 2;
public FileDataSourceProvider(FileFilter filter, String marker) {
this.filter = filter;
this.marker = marker;
chooseAgain = false;
}
/**
* Subclasses can set this flag to call chooseFile again if the file
* isn't valid. By default, the file is ignored and nothing happens.
* The file is considered valid if it can provide the desired datasource
* for the id in the 'provide' function.
* In case the file isn't valid, chooseFile is called again.
* Warning: subclasses setting this flag to true should also modify
* chooseFile. The default implementation always return the same file
* from the fileName and never returns null, so this could cause an
* infinite loop. It is the subclass responsability to provide a
* chooseFile function that can be called again.
*/
protected void setChooseFileAgain(boolean chooseAgain) {
this.chooseAgain = chooseAgain;
}
protected boolean getChooseFileAgain() {
return chooseAgain;
}
/**
* Provides a file, using the given fileName or not.
* Default implementation just checks if the fileName exists in the
* current directory and returns it.
* Subclasses should overload this function and ask the user for a file.
* @param fileName The default fileName.
* @param reason What to look for.
* @return A candidate File, or null if no File can be provided.
*/
public File chooseFile(String fileName, String reason) {
return FileSerializer.readFromString(fileName, null);
}
/**
* Chooses whether to use an already existing collection if it
* contains the datasource to provide, instead of the collection
* with the given id.
* Default implementation says no.
* @param existingDsc The existing collection
* @param dscId The collection id to replace
* @param id The source id present in both collections
* @return YES_OPTION to use the collection present in the pool, NO_OPTION to choose collection with given id,
*/
public int chooseUseCollection(DataSourceCollection existingDsc, String dscId, String Id) {
return NO_OPTION;
}
/**
* Chooses whether to use created collection even if required data source is missing
* Default implementation says YES_OPTION.
* @param dscId The created collection id
* @param dsMissingId The required data source id
* @return YES_OPTION to use the collection, NO_OPTION to choose another collection, CANCEL_OPTION to cancel opening process
*/
protected int chooseUseCollectionIfMissingDs(String dscId, String dsMissingId){
return YES_OPTION;
}
protected abstract DataSource createEmptyDatasource(String dsId, String dscId, Object optionalInformation);
protected DataSourceCollection createCollection(File f, Object optionalInformation) throws IOException, InvalidFormatException{
throw new InvalidFormatException("Unable to restore " + f.getAbsolutePath());
}
/* (non-Javadoc)
* @see simtools.data.DataSourceProvider#getOptionalInformation(simtools.data.DataSource, simtools.data.DataSourceCollection)
*/
public Object getOptionalInformation(DataSource ds, DataSourceCollection dsc) {
return null;
}
/* (non-Javadoc)
* @see simtools.data.DataSourceProvider#provide(java.lang.String, java.lang.String, java.lang.Object, simtools.data.DataSourcePool)
*/
public DataSource provide(String id, String dscId, Object optionalInformation, DataSourcePool pool){
if ((id == null) || (dscId == null) || (!dscId.startsWith(marker)))
return null;
DataSourceCollection existingDsc = null;
if (pool != null){
try {
existingDsc = pool.getCollectionForDataSourceId(id);
} catch (DuplicateIdException e) {
if (e.conflicts.size() == 0)
existingDsc = null;
else if (e.conflicts.size() > 0)
existingDsc = (DataSourceCollection) e.conflicts.get(0);
}
}
if (existingDsc instanceof DataSourceCollection){
if (chooseUseCollection(existingDsc, dscId, id)==YES_OPTION)
return existingDsc.get(id);
}
// Check if an empty data source shall be returned
if (EmptyDataSourcePool.global.containsEmptyCollection(dscId)){
DataSource emptyDs;
if ((emptyDs = (DataSource)EmptyDataSourcePool.global.getEmptyDataSource(id))==null){
emptyDs = createEmptyDatasource(id, dscId, optionalInformation);
EmptyDataSourcePool.global.addEmptyDaSource(id, (EmptyDataSource)emptyDs);
}
if (emptyDs!=null)
return emptyDs;
}
DataSource foundDS = null;
DataSourceCollection adsc = null;
String fileName = dscId.substring(marker.length());
do {
File f = chooseFile(fileName, id);
if ( (f != null) && (f.exists()) ){
try {
adsc = createCollection(f,optionalInformation);
if ((adsc==null) || !(adsc instanceof DataSourceCollection)){
return null;
}
for (int i = 0; i < adsc.size(); ++i) {
if (id.equals( adsc.getInformation(i).id)) {
foundDS = (DataSource) adsc.get(i);
break;
}
}
} catch (Exception e) {}
}
if (foundDS==null){
int answer = chooseUseCollectionIfMissingDs(DataInfo.getLabel(adsc), id);
// If user has confirmed, return as empty data source
if (answer== YES_OPTION){
// Mark collection as empty and return a corresponding empty data source
EmptyDataSourcePool.global.addEmptyCollection(dscId);
if ((foundDS = (DataSource) EmptyDataSourcePool.global.getEmptyDataSource(id))==null){
foundDS = createEmptyDatasource(id, dscId, optionalInformation);
if (foundDS!=null)
EmptyDataSourcePool.global.addEmptyDaSource(id, (EmptyDataSource)foundDS);
}
}
}
} while (getChooseFileAgain() && (foundDS == null));
if ( (foundDS != null) && (adsc!=null) && (pool != null))
pool.addDataSourceCollection(adsc);
return foundDS;
}
}