Hello BASE team,We really enjoy the set of batch uploading plugins and were doing a little training for our users in Bergen. Everything seemed great except that they couldn't link freshly created scans with image files. I read in the example spreadsheet that it is not supported and was very surprised since similar 'file attaching' works very nice for raw bioassays. I sat down, did some copy pasting from RawBioAssayImporter and after little edits it worked (source attached).
I hope that you can make some use of it. All the best, Pawel
/** $Id: ScanImporter.java 4551 2008-09-29 07:47:24Z nicklas $ Copyright (C) 2008 Nicklas Nordborg This file is part of BASE - BioArray Software Environment. Available at http://base.thep.lu.se/ BASE 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. BASE 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 BASE. If not, see <http://www.gnu.org/licenses/>. */ package net.sf.basedb.plugins.batchimport; import java.util.Collections; import java.util.List; import java.util.Set; import net.sf.basedb.core.DbControl; import net.sf.basedb.core.File; import net.sf.basedb.core.Hardware; import net.sf.basedb.core.Hybridization; import net.sf.basedb.core.Image; import net.sf.basedb.core.Item; import net.sf.basedb.core.ItemQuery; import net.sf.basedb.core.Path; import net.sf.basedb.core.PathParameterType; import net.sf.basedb.core.PluginParameter; import net.sf.basedb.core.Protocol; import net.sf.basedb.core.ProtocolType; import net.sf.basedb.core.Scan; import net.sf.basedb.core.SystemItems; import net.sf.basedb.core.Version; import net.sf.basedb.core.plugin.About; import net.sf.basedb.core.plugin.AboutImpl; import net.sf.basedb.core.plugin.GuiContext; import net.sf.basedb.util.parser.FlatFileParser; import net.sf.basedb.util.parser.Mapper; /** Plug-in for importing scan items in a batch. The plug-in can create new items and updated existing items. @author nicklas @version 2.8 @base.modified $Date: 2008-09-29 09:47:24 +0200 (Mon, 29 Sep 2008) $ */ public class ScanImporterNMC extends AbstractItemImporter<Scan> { private static final Set<GuiContext> guiContexts = Collections.singleton(new GuiContext(Item.SCAN, GuiContext.Type.LIST)); private static final About about = new AboutImpl ( "Scan importer with images", "Imports and updates scans in a batch (linking with images).", Version.getMajor() + "." + Version.getMinor() + "." + Version.getMaintenance(), "2008, Base 2 development team", null, null, "http://base.thep.lu.se" ); protected static final PluginParameter<String> hardwareColumnMapping = new PluginParameter<String>( "hardwareColumnMapping", "Scanner", "Mapping that picks the name or ID of the array slide scanner from the data columns. " + "The plug-in will first try to find a scanner with the given name. If none is found and " + "the value is numeric it will try to load by internal ID. " + "Example: \\Scanner\\", optionalColumnMapping ); protected static final PluginParameter<String> hybridizationColumnMapping = new PluginParameter<String>( "hybridizationColumnMapping", "Hybridization", "Mapping that picks the name or ID of the hybridization from the data columns. " + "The plug-in will first try to find a hybridization with the given name. If none is found and " + "the value is numeric it will try to load by internal ID. " + "Example: \\Hybridization\\", optionalColumnMapping ); // extra parameter needed for linking with image files protected static final PluginParameter<String> fileColumnMapping = new PluginParameter<String>( "fileColumnMapping", "File", "Mapping that picks the path of a image file from the columns. " + "The path can be an absolute path (starting with /) or relative " + "to the 'Data directory' parameter." + "Example: \\File\\", optionalColumnMapping ); public ScanImporterNMC() {} /* From the Plugin interface ------------------------------------ */ @Override public About getAbout() { return about; } // ------------------------------------ /* From the InteractivePlugin interface ------------------------------------ */ @Override public Set<GuiContext> getGuiContexts() { return guiContexts; } // ------------------------------------ /* From the AbstractItemImporter class ------------------------------------ */ private Mapper nameMapper; private Mapper descriptionMapper; private Mapper protocolMapper; private Mapper hardwareMapper; private Mapper hybridizationMapper; //extra mappers for linking with image file private Mapper fileMapper; private String imagesDirectory; /** Useable methods are: <ul> <li>{...@link PropertyIdMethod#NAME} <li>{...@link InternalIdMethod#INTERNAL_ID} <li>{...@link FallbackIdMethod#NAME_OR_ID} </ul> */ @Override protected IdMethod[] getIdMethods() { return new IdMethod[] { PropertyIdMethod.NAME, InternalIdMethod.INTERNAL_ID, FallbackIdMethod.NAME_OR_ID}; } /** Add parameter for "Image directory" directory where image files may be located. */ @Override protected void addMoreJobParameters(List<PluginParameter<?>> parameters) { parameters.add(new PluginParameter<String>( "imagesDirectory", "Images directory", "A base directory were image files are located. Relative file paths are " + "resolved against this directory. If no directory is given, only absolute " + "paths (=paths starting with /) can be used.", new PathParameterType(Path.Type.DIRECTORY)) ); } /** Adds column mappings for name, externalId, description, protocol, creation date, original quantity, pooled, parent and used quantity from parent. */ @Override protected void addMoreColumnMappingParameters(List<PluginParameter<?>> parameters) { parameters.add(internalIdColumnMapping); parameters.add(nameColumnMapping); parameters.add(descriptionColumnMapping); parameters.add(hybridizationColumnMapping); parameters.add(protocolColumnMapping); parameters.add(hardwareColumnMapping); parameters.add(fileColumnMapping); } /** Calls {...@link Scan#getQuery()}. */ @Override protected ItemQuery<Scan> createItemQuery() { return Scan.getQuery(); } @Override protected void createColumnMappers(FlatFileParser ffp, boolean cropStrings) { nameMapper = getMapper(ffp, (String)job.getValue("nameColumnMapping"), cropStrings ? Scan.MAX_NAME_LENGTH : null, null); descriptionMapper = getMapper(ffp, (String)job.getValue("descriptionColumnMapping"), cropStrings ? Scan.MAX_DESCRIPTION_LENGTH : null, null); protocolMapper = getMapper(ffp, (String)job.getValue("protocolColumnMapping"), null, null); hardwareMapper = getMapper(ffp, (String)job.getValue("hardwareColumnMapping"), null, null); hybridizationMapper = getMapper(ffp, (String)job.getValue("hybridizationColumnMapping"), null, null); fileMapper = getMapper(ffp, (String)job.getValue("fileColumnMapping"), null, null); imagesDirectory = (String)job.getValue("imagesDirectory"); if (imagesDirectory != null && !imagesDirectory.endsWith("/")) { imagesDirectory += "/"; } } @Override protected Scan createItem(DbControl dc, FlatFileParser.Data data) { Hybridization hyb = null; if (hybridizationMapper != null) { hyb = findHybridization(dc, FallbackIdMethod.NAME_OR_ID, hybridizationMapper.getValue(data)); } Scan scan = Scan.getNew(dc, hyb); updateItem(dc, scan, data); return scan; } @Override protected void updateItem(DbControl dc, Scan scan, FlatFileParser.Data data) { if (nameMapper != null) scan.setName(nameMapper.getValue(data)); if (descriptionMapper != null) scan.setDescription(descriptionMapper.getValue(data)); if (hybridizationMapper != null && scan.isInDatabase()) { String nameOrId = hybridizationMapper.getValue(data); if (nameOrId != null) { Hybridization hyb = findHybridization(dc, FallbackIdMethod.NAME_OR_ID, hybridizationMapper.getValue(data)); scan.setHybridization(hyb); } } if (protocolMapper != null) { String nameOrId = protocolMapper.getValue(data); ProtocolType type = ProtocolType.getById(dc, SystemItems.getId(ProtocolType.SCANNING)); Protocol protocol = findProtocol(dc, FallbackIdMethod.NAME_OR_ID, nameOrId, type); if (nameOrId == null || protocol != null) scan.setProtocol(protocol); } if (hardwareMapper != null) { String nameOrId = hardwareMapper.getValue(data); Hardware scanner = findScanner(dc, FallbackIdMethod.NAME_OR_ID, nameOrId); if (nameOrId == null || scanner != null) scan.setScanner(scanner); } updateMultiLineItem(dc, scan, data, 0); } protected void updateMultiLineItem(DbControl dc, Scan scan, FlatFileParser.Data data, int multiLineNum) { if (fileMapper != null) { String filePath = fileMapper.getValue(data); File file = null; if (filePath != null) { if (!filePath.startsWith("/") && imagesDirectory != null) { filePath = imagesDirectory + filePath; } file = File.getByPath(dc, new Path(filePath, Path.Type.FILE), false); } if (file != null) { Image image = scan.newImage(); image.setFile(file); image.setName(scan.getName()+"_"+file.getName()); dc.saveItemIf(scan, image, false); } } } }
------------------------------------------------------------------------------ Apps built with the Adobe(R) Flex(R) framework and Flex Builder(TM) are powering Web 2.0 with engaging, cross-platform capabilities. Quickly and easily build your RIAs with Flex Builder, the Eclipse(TM)based development software that enables intelligent coding and step-through debugging. Download the free 60 day trial. http://p.sf.net/sfu/www-adobe-com
_______________________________________________ basedb-devel mailing list basedb-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/basedb-devel