src/core/net/sf/basedb/util/AutoDetectFileFormat.java

Code
Comments
Other
Rev Date Author Line
1613 15 Nov 05 nicklas 1 /*
1613 15 Nov 05 nicklas 2   $Id$
1613 15 Nov 05 nicklas 3
3675 16 Aug 07 jari 4   Copyright (C) 2005 Nicklas Nordborg
4889 06 Apr 09 nicklas 5   Copyright (C) 2006 Jari Häkkinen, Nicklas Nordborg
3675 16 Aug 07 jari 6   Copyright (C) 2007 Nicklas Nordborg
1613 15 Nov 05 nicklas 7
2304 22 May 06 jari 8   This file is part of BASE - BioArray Software Environment.
2304 22 May 06 jari 9   Available at http://base.thep.lu.se/
1613 15 Nov 05 nicklas 10
1613 15 Nov 05 nicklas 11   BASE is free software; you can redistribute it and/or
1613 15 Nov 05 nicklas 12   modify it under the terms of the GNU General Public License
4479 05 Sep 08 jari 13   as published by the Free Software Foundation; either version 3
1613 15 Nov 05 nicklas 14   of the License, or (at your option) any later version.
1613 15 Nov 05 nicklas 15
1613 15 Nov 05 nicklas 16   BASE is distributed in the hope that it will be useful,
1613 15 Nov 05 nicklas 17   but WITHOUT ANY WARRANTY; without even the implied warranty of
1613 15 Nov 05 nicklas 18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1613 15 Nov 05 nicklas 19   GNU General Public License for more details.
1613 15 Nov 05 nicklas 20
1613 15 Nov 05 nicklas 21   You should have received a copy of the GNU General Public License
4515 11 Sep 08 jari 22   along with BASE. If not, see <http://www.gnu.org/licenses/>.
1613 15 Nov 05 nicklas 23 */
1613 15 Nov 05 nicklas 24 package net.sf.basedb.util;
1613 15 Nov 05 nicklas 25
1613 15 Nov 05 nicklas 26 import net.sf.basedb.core.SessionControl;
1613 15 Nov 05 nicklas 27 import net.sf.basedb.core.DbControl;
1613 15 Nov 05 nicklas 28 import net.sf.basedb.core.BaseException;
1617 16 Nov 05 nicklas 29 import net.sf.basedb.core.InvalidDataException;
1617 16 Nov 05 nicklas 30 import net.sf.basedb.core.InvalidUseOfNullException;
1613 15 Nov 05 nicklas 31 import net.sf.basedb.core.File;
1617 16 Nov 05 nicklas 32 import net.sf.basedb.core.Include;
1617 16 Nov 05 nicklas 33 import net.sf.basedb.core.Location;
1613 15 Nov 05 nicklas 34 import net.sf.basedb.core.ItemQuery;
1613 15 Nov 05 nicklas 35 import net.sf.basedb.core.PluginConfiguration;
1613 15 Nov 05 nicklas 36 import net.sf.basedb.core.PluginDefinition;
5615 19 Apr 11 nicklas 37 import net.sf.basedb.core.query.Expressions;
1772 16 Jan 06 nicklas 38 import net.sf.basedb.core.query.Orders;
1772 16 Jan 06 nicklas 39 import net.sf.basedb.core.query.Hql;
5615 19 Apr 11 nicklas 40 import net.sf.basedb.core.query.Restrictions;
1613 15 Nov 05 nicklas 41 import net.sf.basedb.core.plugin.AutoDetectingImporter;
1701 09 Dec 05 nicklas 42 import net.sf.basedb.core.plugin.GuiContext;
1772 16 Jan 06 nicklas 43 import net.sf.basedb.core.plugin.InteractivePlugin;
4594 21 Oct 08 nicklas 44 import net.sf.basedb.util.ContextUtil.ContextResult;
4594 21 Oct 08 nicklas 45 import net.sf.basedb.util.filter.Filter;
1613 15 Nov 05 nicklas 46
1613 15 Nov 05 nicklas 47 import java.util.List;
1613 15 Nov 05 nicklas 48 import java.util.LinkedList;
1772 16 Jan 06 nicklas 49 import java.util.Map;
1772 16 Jan 06 nicklas 50 import java.util.LinkedHashMap;
1772 16 Jan 06 nicklas 51 import java.util.Collections;
1613 15 Nov 05 nicklas 52 import java.io.InputStream;
1613 15 Nov 05 nicklas 53
1613 15 Nov 05 nicklas 54 /**
1613 15 Nov 05 nicklas 55   This class has methods for autodetecting file formats.
1613 15 Nov 05 nicklas 56
1613 15 Nov 05 nicklas 57   @author Nicklas
1613 15 Nov 05 nicklas 58   @version 2.0
1613 15 Nov 05 nicklas 59   @base.modified $Date$
1613 15 Nov 05 nicklas 60 */
1613 15 Nov 05 nicklas 61 public class AutoDetectFileFormat
1613 15 Nov 05 nicklas 62 {
1613 15 Nov 05 nicklas 63
1617 16 Nov 05 nicklas 64   /**
1772 16 Jan 06 nicklas 65     Find all plugins with configurations which can import the specified file. 
1617 16 Nov 05 nicklas 66     This method will check all plugins implementing the {@link
1617 16 Nov 05 nicklas 67     AutoDetectingImporter} interface if they can import the specified file.
1617 16 Nov 05 nicklas 68     
1617 16 Nov 05 nicklas 69     @param dc The <code>DbControl</code> object to use for database access
1772 16 Jan 06 nicklas 70     @param context A required context for the plugins (ie. what items to import)
1617 16 Nov 05 nicklas 71     @param file The file to import
4525 16 Sep 08 nicklas 72     @param charset If given, overrides the character set specified by the file
4525 16 Sep 08 nicklas 73       {@link File#getCharacterSet()}
1772 16 Jan 06 nicklas 74     @param pluginDef Check only the configurations of this plugin definition, or
1772 16 Jan 06 nicklas 75       null if all plugin definitions should be checked
1772 16 Jan 06 nicklas 76     @return A map which for each plugin definition contains a list
1772 16 Jan 06 nicklas 77       of mathching configurations
1617 16 Nov 05 nicklas 78     @throws InvalidDataException If the file parameter is null or if
1617 16 Nov 05 nicklas 79       the file isn't located in {@link Location#PRIMARY} storage
1617 16 Nov 05 nicklas 80     @throws BaseException If there is another error
4525 16 Sep 08 nicklas 81     @since 2.9
1617 16 Nov 05 nicklas 82   */
4525 16 Sep 08 nicklas 83   public static Map<PluginDefinition, List<PluginConfiguration>> findPlugins(DbControl dc, 
4525 16 Sep 08 nicklas 84     GuiContext context, File file, String charset, PluginDefinition pluginDef)
1617 16 Nov 05 nicklas 85     throws InvalidDataException, BaseException
1613 15 Nov 05 nicklas 86   {
1617 16 Nov 05 nicklas 87     if (file == null) throw new InvalidUseOfNullException("file");
5327 29 Apr 10 nicklas 88     if (!file.getLocation().isDownloadable())
1617 16 Nov 05 nicklas 89     {
5327 29 Apr 10 nicklas 90       throw new InvalidDataException("Can't download file data for file '" + 
5327 29 Apr 10 nicklas 91           file.getName() + "'; location=" + file.getLocation());
1617 16 Nov 05 nicklas 92     }
1613 15 Nov 05 nicklas 93     SessionControl sc = dc.getSessionControl();
1772 16 Jan 06 nicklas 94     Object currentItem = null;
1772 16 Jan 06 nicklas 95     if (context.getType() == GuiContext.Type.ITEM)
1772 16 Jan 06 nicklas 96     {
1772 16 Jan 06 nicklas 97       currentItem = context.getItem().getById(dc, sc.getCurrentContext(context.getItem()).getId());
1772 16 Jan 06 nicklas 98     }
1617 16 Nov 05 nicklas 99
1772 16 Jan 06 nicklas 100     Map<PluginDefinition, List<PluginConfiguration>> plugins = 
1772 16 Jan 06 nicklas 101       new LinkedHashMap<PluginDefinition, List<PluginConfiguration>>();
3564 17 Jul 07 nicklas 102     
1772 16 Jan 06 nicklas 103     List<PluginDefinition> pluginDefs = null;
1772 16 Jan 06 nicklas 104     if (pluginDef == null)
1613 15 Nov 05 nicklas 105     {
1772 16 Jan 06 nicklas 106       ItemQuery<PluginDefinition> pluginQuery = 
1772 16 Jan 06 nicklas 107         PluginDefinition.getQuery(context, AutoDetectingImporter.class.getName());
1772 16 Jan 06 nicklas 108       pluginQuery.order(Orders.asc(Hql.property("name")));
5615 19 Apr 11 nicklas 109       pluginQuery.restrict(Restrictions.eq(Hql.property("disabled"), Expressions.parameter("isDisabled", false)));
1772 16 Jan 06 nicklas 110       pluginQuery.include(Include.MINE, Include.SHARED, Include.IN_PROJECT, Include.OTHERS);
1772 16 Jan 06 nicklas 111       pluginDefs = pluginQuery.list(dc);
1772 16 Jan 06 nicklas 112     }
1772 16 Jan 06 nicklas 113     else
1772 16 Jan 06 nicklas 114     {
1772 16 Jan 06 nicklas 115       pluginDefs = Collections.singletonList(pluginDef);
1772 16 Jan 06 nicklas 116     }
1772 16 Jan 06 nicklas 117     
1772 16 Jan 06 nicklas 118     for (PluginDefinition plugin : pluginDefs)
1772 16 Jan 06 nicklas 119     {
1772 16 Jan 06 nicklas 120       List<PluginConfiguration> configs = new LinkedList<PluginConfiguration>();
3564 17 Jul 07 nicklas 121       if (!plugin.requiresConfiguration())
1613 15 Nov 05 nicklas 122       {
4525 16 Sep 08 nicklas 123         if (checkImportable(sc, plugin, null, file, charset, context, currentItem))
1772 16 Jan 06 nicklas 124         {
3564 17 Jul 07 nicklas 125           configs.add(null);
3564 17 Jul 07 nicklas 126         }
3564 17 Jul 07 nicklas 127       }
3564 17 Jul 07 nicklas 128       if (plugin.supportsConfigurations())
3564 17 Jul 07 nicklas 129       {
3564 17 Jul 07 nicklas 130         ItemQuery<PluginConfiguration> configQuery = plugin.getPluginConfigurations();
5629 09 May 11 nicklas 131         configQuery.restrict(Restrictions.gt(Hql.property("parameterVersion"), Expressions.integer(0)));
8107 23 Jan 23 nicklas 132         configQuery.restrict(Restrictions.eq(Hql.property("disabled"), Expressions.parameter("isDisabled", false)));
3564 17 Jul 07 nicklas 133         configQuery.order(Orders.asc(Hql.property("name")));
3564 17 Jul 07 nicklas 134         configQuery.include(Include.MINE, Include.SHARED, Include.IN_PROJECT, Include.OTHERS);
3564 17 Jul 07 nicklas 135         for (PluginConfiguration config : configQuery.list(dc))
3564 17 Jul 07 nicklas 136         {
4525 16 Sep 08 nicklas 137           if (checkImportable(sc, plugin, config, file, charset, context, currentItem))
1772 16 Jan 06 nicklas 138           {
1772 16 Jan 06 nicklas 139             configs.add(config);
1772 16 Jan 06 nicklas 140           }
1772 16 Jan 06 nicklas 141         }
1613 15 Nov 05 nicklas 142       }
3564 17 Jul 07 nicklas 143       if (configs.size() > 0)  plugins.put(plugin, configs);
3564 17 Jul 07 nicklas 144     }
3564 17 Jul 07 nicklas 145     return plugins;
3564 17 Jul 07 nicklas 146   }
3564 17 Jul 07 nicklas 147   
3564 17 Jul 07 nicklas 148   private static boolean checkImportable(SessionControl sc, PluginDefinition plugin, 
4525 16 Sep 08 nicklas 149     PluginConfiguration config, File file, String charset, GuiContext context, Object currentItem)
3564 17 Jul 07 nicklas 150   {
3564 17 Jul 07 nicklas 151     AutoDetectingImporter importer = null;
3564 17 Jul 07 nicklas 152     boolean canBeUsed = false;
3564 17 Jul 07 nicklas 153     try
3564 17 Jul 07 nicklas 154     {
5595 17 Mar 11 nicklas 155       importer = plugin.newInstance(AutoDetectingImporter.class, sc, config, null);
3564 17 Jul 07 nicklas 156       boolean isInContext = true;
4594 21 Oct 08 nicklas 157       if (plugin.isInteractive() && context != null)
1613 15 Nov 05 nicklas 158       {
3564 17 Jul 07 nicklas 159         try
3564 17 Jul 07 nicklas 160         {
3564 17 Jul 07 nicklas 161           InteractivePlugin ip = (InteractivePlugin)importer;
3564 17 Jul 07 nicklas 162           isInContext = ip.isInContext(context, currentItem) == null;
3564 17 Jul 07 nicklas 163         }
3564 17 Jul 07 nicklas 164         catch (Throwable t)
3564 17 Jul 07 nicklas 165         {
3564 17 Jul 07 nicklas 166           isInContext = false;
3564 17 Jul 07 nicklas 167         }
1613 15 Nov 05 nicklas 168       }
3564 17 Jul 07 nicklas 169       if (isInContext)
1772 16 Jan 06 nicklas 170       {
4525 16 Sep 08 nicklas 171         InputStream in = new FileImportInputStream(file, 0, charset);
3564 17 Jul 07 nicklas 172         try
1772 16 Jan 06 nicklas 173         {
3564 17 Jul 07 nicklas 174           canBeUsed = importer.isImportable(in);
3564 17 Jul 07 nicklas 175         }
3564 17 Jul 07 nicklas 176         catch (Throwable t)
3564 17 Jul 07 nicklas 177         {
3564 17 Jul 07 nicklas 178           canBeUsed = false;
3564 17 Jul 07 nicklas 179         }
3564 17 Jul 07 nicklas 180         finally
3564 17 Jul 07 nicklas 181         {
1772 16 Jan 06 nicklas 182           try
1772 16 Jan 06 nicklas 183           {
1772 16 Jan 06 nicklas 184             in.close();
1772 16 Jan 06 nicklas 185           }
3564 17 Jul 07 nicklas 186           catch (Throwable t)
1772 16 Jan 06 nicklas 187           {}
1772 16 Jan 06 nicklas 188         }
3564 17 Jul 07 nicklas 189       }      
1613 15 Nov 05 nicklas 190     }
3564 17 Jul 07 nicklas 191     finally
3564 17 Jul 07 nicklas 192     {
3564 17 Jul 07 nicklas 193       if (importer != null) importer.done();
3564 17 Jul 07 nicklas 194     }
3564 17 Jul 07 nicklas 195     return canBeUsed;
1613 15 Nov 05 nicklas 196   }
3564 17 Jul 07 nicklas 197   
4594 21 Oct 08 nicklas 198   /**
4594 21 Oct 08 nicklas 199     Filter implementation that filters a collection of
4594 21 Oct 08 nicklas 200     {@link ContextResult}:s by checking each plug-ins ability to
4594 21 Oct 08 nicklas 201     import a given file. Eg. the ContextResult is accepted if the
4594 21 Oct 08 nicklas 202     {@link AutoDetectingImporter#isImportable(InputStream)} returns
4594 21 Oct 08 nicklas 203     true. It is assumed that the collection of ContextResult:s only
4594 21 Oct 08 nicklas 204     contains import plug-ins that implements the AutoDetectingImporter 
4594 21 Oct 08 nicklas 205     interface.
4594 21 Oct 08 nicklas 206   
4594 21 Oct 08 nicklas 207     @author Nicklas
4594 21 Oct 08 nicklas 208     @version 2.9
4594 21 Oct 08 nicklas 209     @base.modified $Date$
4594 21 Oct 08 nicklas 210   */
4594 21 Oct 08 nicklas 211   public static class IsImportableFilter
4594 21 Oct 08 nicklas 212     implements Filter<ContextResult>
4594 21 Oct 08 nicklas 213   {
4594 21 Oct 08 nicklas 214     private File file;
4594 21 Oct 08 nicklas 215     private Filter<? super ContextResult> parent;
4594 21 Oct 08 nicklas 216     
4594 21 Oct 08 nicklas 217     public IsImportableFilter(File file, Filter<? super ContextResult> parent)
4594 21 Oct 08 nicklas 218     {
4594 21 Oct 08 nicklas 219       this.file = file;
4594 21 Oct 08 nicklas 220       this.parent = parent;
4594 21 Oct 08 nicklas 221     }
4594 21 Oct 08 nicklas 222     
6127 14 Sep 12 nicklas 223     @Override
4594 21 Oct 08 nicklas 224     public boolean evaluate(ContextResult result)
4594 21 Oct 08 nicklas 225     {
4594 21 Oct 08 nicklas 226       if (result == null) return false;
4594 21 Oct 08 nicklas 227       if (parent != null && !parent.evaluate(result)) return false;
4594 21 Oct 08 nicklas 228       if (!result.isInContext()) return false;
4594 21 Oct 08 nicklas 229       return checkImportable(file.getSessionControl(), 
4594 21 Oct 08 nicklas 230           result.getPluginDefinition(), result.getPluginConfiguration(), file, 
4594 21 Oct 08 nicklas 231           null, null, null);
4594 21 Oct 08 nicklas 232     }
4594 21 Oct 08 nicklas 233   }
4594 21 Oct 08 nicklas 234   
1613 15 Nov 05 nicklas 235 }