src/plugins/core/net/sf/basedb/plugins/ReporterFlatFileImporter.java

Code
Comments
Other
Rev Date Author Line
1244 05 Sep 05 nicklas 1 /*
1244 05 Sep 05 nicklas 2   $Id$
1244 05 Sep 05 nicklas 3
3675 16 Aug 07 jari 4   Copyright (C) 2005 Johan Enell, Nicklas Nordborg
4889 06 Apr 09 nicklas 5   Copyright (C) 2006 Johan Enell, Jari Häkkinen, Nicklas Nordborg
3675 16 Aug 07 jari 6   Copyright (C) 2007 Nicklas Nordborg
1244 05 Sep 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/
1244 05 Sep 05 nicklas 10
1244 05 Sep 05 nicklas 11   BASE is free software; you can redistribute it and/or
1244 05 Sep 05 nicklas 12   modify it under the terms of the GNU General Public License
4480 05 Sep 08 jari 13   as published by the Free Software Foundation; either version 3
1244 05 Sep 05 nicklas 14   of the License, or (at your option) any later version.
1244 05 Sep 05 nicklas 15
1244 05 Sep 05 nicklas 16   BASE is distributed in the hope that it will be useful,
1244 05 Sep 05 nicklas 17   but WITHOUT ANY WARRANTY; without even the implied warranty of
1244 05 Sep 05 nicklas 18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1244 05 Sep 05 nicklas 19   GNU General Public License for more details.
1244 05 Sep 05 nicklas 20
1244 05 Sep 05 nicklas 21   You should have received a copy of the GNU General Public License
4513 11 Sep 08 jari 22   along with BASE. If not, see <http://www.gnu.org/licenses/>.
1244 05 Sep 05 nicklas 23 */
1244 05 Sep 05 nicklas 24 package net.sf.basedb.plugins;
1244 05 Sep 05 nicklas 25
4076 11 Jan 08 martin 26 import net.sf.basedb.core.File;
3596 24 Jul 07 nicklas 27 import net.sf.basedb.core.HibernateUtil;
2751 20 Oct 06 nicklas 28 import net.sf.basedb.core.InvalidUseOfNullException;
2186 25 Apr 06 nicklas 29 import net.sf.basedb.core.ItemContext;
3596 24 Jul 07 nicklas 30 import net.sf.basedb.core.ItemInUseException;
2722 11 Oct 06 nicklas 31 import net.sf.basedb.core.Permission;
5241 10 Feb 10 nicklas 32 import net.sf.basedb.core.PermissionDeniedException;
2149 04 Apr 06 nicklas 33 import net.sf.basedb.core.ReporterList;
1244 05 Sep 05 nicklas 34 import net.sf.basedb.core.RequestInformation;
1244 05 Sep 05 nicklas 35 import net.sf.basedb.core.PluginParameter;
1244 05 Sep 05 nicklas 36 import net.sf.basedb.core.ExtendedProperties;
1244 05 Sep 05 nicklas 37 import net.sf.basedb.core.ExtendedProperty;
1244 05 Sep 05 nicklas 38 import net.sf.basedb.core.ReporterType;
1244 05 Sep 05 nicklas 39 import net.sf.basedb.core.DbControl;
1244 05 Sep 05 nicklas 40 import net.sf.basedb.core.ItemParameterType;
1248 06 Sep 05 nicklas 41 import net.sf.basedb.core.StringParameterType;
1244 05 Sep 05 nicklas 42 import net.sf.basedb.core.BaseException;
1292 08 Sep 05 nicklas 43 import net.sf.basedb.core.ItemNotFoundException;
1256 06 Sep 05 nicklas 44 import net.sf.basedb.core.Reporter;
1256 06 Sep 05 nicklas 45 import net.sf.basedb.core.ReporterBatcher;
1267 07 Sep 05 nicklas 46 import net.sf.basedb.core.Item;
1759 12 Jan 06 nicklas 47 import net.sf.basedb.core.ItemQuery;
1626 17 Nov 05 nicklas 48 import net.sf.basedb.core.Job;
2149 04 Apr 06 nicklas 49 import net.sf.basedb.core.Type;
2838 31 Oct 06 enell 50 import net.sf.basedb.core.query.Expressions;
1759 12 Jan 06 nicklas 51 import net.sf.basedb.core.query.Orders;
2838 31 Oct 06 enell 52 import net.sf.basedb.core.query.Restrictions;
1759 12 Jan 06 nicklas 53 import net.sf.basedb.core.query.Hql;
1244 05 Sep 05 nicklas 54
1256 06 Sep 05 nicklas 55 import net.sf.basedb.core.data.ReporterData;
1256 06 Sep 05 nicklas 56
1376 22 Sep 05 nicklas 57 import net.sf.basedb.core.plugin.InteractivePlugin;
2722 11 Oct 06 nicklas 58 import net.sf.basedb.core.plugin.Permissions;
1244 05 Sep 05 nicklas 59 import net.sf.basedb.core.plugin.Request;
1248 06 Sep 05 nicklas 60 import net.sf.basedb.core.plugin.Response;
1701 09 Dec 05 nicklas 61 import net.sf.basedb.core.plugin.GuiContext;
1244 05 Sep 05 nicklas 62
4107 29 Jan 08 nicklas 63 import net.sf.basedb.plugins.util.Parameters;
3596 24 Jul 07 nicklas 64 import net.sf.basedb.util.error.SimpleErrorHandler;
2655 22 Sep 06 nicklas 65 import net.sf.basedb.util.parser.ConfigureByExample;
2751 20 Oct 06 nicklas 66 import net.sf.basedb.util.parser.ConstantMapper;
2203 28 Apr 06 nicklas 67 import net.sf.basedb.util.parser.FlatFileParser;
2203 28 Apr 06 nicklas 68 import net.sf.basedb.util.parser.Mapper;
1244 05 Sep 05 nicklas 69
2722 11 Oct 06 nicklas 70 import java.util.Collection;
2722 11 Oct 06 nicklas 71 import java.util.EnumSet;
2149 04 Apr 06 nicklas 72 import java.util.HashSet;
1244 05 Sep 05 nicklas 73 import java.util.List;
1244 05 Sep 05 nicklas 74 import java.util.ArrayList;
1248 06 Sep 05 nicklas 75 import java.util.Arrays;
1263 06 Sep 05 nicklas 76 import java.util.Map;
1263 06 Sep 05 nicklas 77 import java.util.HashMap;
1267 07 Sep 05 nicklas 78 import java.util.Set;
3596 24 Jul 07 nicklas 79 import java.util.TreeSet;
1244 05 Sep 05 nicklas 80
1244 05 Sep 05 nicklas 81 /**
1244 05 Sep 05 nicklas 82   A plugin that imports reporter from a flat file.
1244 05 Sep 05 nicklas 83   
1244 05 Sep 05 nicklas 84   @base.modified $Date$
1244 05 Sep 05 nicklas 85   @author Nicklas
1244 05 Sep 05 nicklas 86   @version 2.0
1244 05 Sep 05 nicklas 87 */
1244 05 Sep 05 nicklas 88 public class ReporterFlatFileImporter 
1244 05 Sep 05 nicklas 89   extends AbstractFlatFileImporter
2655 22 Sep 06 nicklas 90   implements InteractivePlugin, ConfigureByExample
1244 05 Sep 05 nicklas 91 {
1244 05 Sep 05 nicklas 92
1701 09 Dec 05 nicklas 93   private static final Set<GuiContext> guiContexts = 
2149 04 Apr 06 nicklas 94     new HashSet<GuiContext>(Arrays.asList(
2149 04 Apr 06 nicklas 95       new GuiContext(Item.REPORTER, GuiContext.Type.LIST),
2150 05 Apr 06 nicklas 96       new GuiContext(Item.REPORTERLIST, GuiContext.Type.ITEM),
2150 05 Apr 06 nicklas 97       new GuiContext(Item.REPORTERSCORE, GuiContext.Type.LIST)
2149 04 Apr 06 nicklas 98     ));
2722 11 Oct 06 nicklas 99   
2722 11 Oct 06 nicklas 100   private static final Set<Permissions> permissions = new HashSet<Permissions>();
1701 09 Dec 05 nicklas 101
1554 02 Nov 05 enell 102   private static final StringParameterType requiredColumnMapping = new StringParameterType(255, null, true);
1554 02 Nov 05 enell 103   private static final StringParameterType optionalColumnMapping = new StringParameterType(255, null, false);
1292 08 Sep 05 nicklas 104   
1248 06 Sep 05 nicklas 105   private static final PluginParameter<String> nameColumnMapping = new PluginParameter<String>(
1248 06 Sep 05 nicklas 106     "nameColumnMapping",
1248 06 Sep 05 nicklas 107     "Name",
2324 24 May 06 nicklas 108     "Mapping that picks the reporter's name from the data columns. " +
2324 24 May 06 nicklas 109     "For example: \\Name\\",
1265 06 Sep 05 nicklas 110     requiredColumnMapping
1248 06 Sep 05 nicklas 111     );
1248 06 Sep 05 nicklas 112   
1248 06 Sep 05 nicklas 113   private static final PluginParameter<String> reporterIdColumnMapping = new PluginParameter<String>(
1248 06 Sep 05 nicklas 114     "reporterIdColumnMapping",
4626 05 Nov 08 nicklas 115     "External ID",
4626 05 Nov 08 nicklas 116     "Mapping that picks the reporter's external ID from the data columns. " +
2324 24 May 06 nicklas 117     "For example: \\ID\\",
1265 06 Sep 05 nicklas 118     requiredColumnMapping
1248 06 Sep 05 nicklas 119     );
1263 06 Sep 05 nicklas 120   
1263 06 Sep 05 nicklas 121   private static final PluginParameter<String> descriptionColumnMapping = new PluginParameter<String>(
1263 06 Sep 05 nicklas 122     "descriptionColumnMapping",
1263 06 Sep 05 nicklas 123     "Description",
2324 24 May 06 nicklas 124     "Mapping that picks the reporter's description from the data columns. " +
2324 24 May 06 nicklas 125     "For example: \\Description\\",
1265 06 Sep 05 nicklas 126     optionalColumnMapping
1263 06 Sep 05 nicklas 127     );
1263 06 Sep 05 nicklas 128   
1263 06 Sep 05 nicklas 129   private static final PluginParameter<String> symbolColumnMapping = new PluginParameter<String>(
1263 06 Sep 05 nicklas 130     "symbolColumnMapping",
1263 06 Sep 05 nicklas 131     "Gene symbol",
2324 24 May 06 nicklas 132     "Mapping that picks the reporter's gene symbol from the data columns. " +
2324 24 May 06 nicklas 133     "For example: \\Gene symbol\\",
1265 06 Sep 05 nicklas 134     optionalColumnMapping
1263 06 Sep 05 nicklas 135     );
1248 06 Sep 05 nicklas 136
2149 04 Apr 06 nicklas 137   private static final PluginParameter<String> scoreColumnMapping = new PluginParameter<String>(
2838 31 Oct 06 enell 138     "scoreColumnMapping",
2838 31 Oct 06 enell 139     "Score",
2838 31 Oct 06 enell 140     "Mapping that picks the reporter's score in some context. This mapping is only " +
2838 31 Oct 06 enell 141       "used when importing to a reporter list.",
2838 31 Oct 06 enell 142     optionalColumnMapping
2838 31 Oct 06 enell 143     );
2149 04 Apr 06 nicklas 144
2838 31 Oct 06 enell 145   private static final PluginParameter<String> reporterTypeColumnMapping = new PluginParameter<String>(
2838 31 Oct 06 enell 146     "reporterTypeColumnMapping",
2838 31 Oct 06 enell 147     "Reporter type",
2838 31 Oct 06 enell 148     "Mapping that pick the reporter's type from the data columns. This will overide the reporter type parameter. For example: \\Reporter type\\",
2838 31 Oct 06 enell 149     optionalColumnMapping
2838 31 Oct 06 enell 150     );
2838 31 Oct 06 enell 151
3596 24 Jul 07 nicklas 152   protected static final PluginParameter<String> reporterIsUsedErrorParameter = new PluginParameter<String>(
3596 24 Jul 07 nicklas 153       "reporterIsUsedError",
3596 24 Jul 07 nicklas 154       "Reporter is used",
3596 24 Jul 07 nicklas 155       "How to handle errors that are caused by a reporter beeing used by other items" +
3596 24 Jul 07 nicklas 156       "and can't be deleted. This option is used in DELETE mode only. " +
3596 24 Jul 07 nicklas 157       "If not specified the default error handling is used.\n\n" +
3596 24 Jul 07 nicklas 158       "skip = Skip the current data line and continue\n"+
3596 24 Jul 07 nicklas 159       "fail = Stop with an error message",
3596 24 Jul 07 nicklas 160       new StringParameterType(255, "skip", false, 1, 0, 0, 
3596 24 Jul 07 nicklas 161           Arrays.asList( new String[] { "skip", "fail"} ))
3596 24 Jul 07 nicklas 162       );  
2838 31 Oct 06 enell 163   
1248 06 Sep 05 nicklas 164   private PluginParameter<ReporterType> reporterTypeParameter;
2149 04 Apr 06 nicklas 165   private PluginParameter<ReporterList> reporterListParameter;
1248 06 Sep 05 nicklas 166   
1263 06 Sep 05 nicklas 167   private List<PluginParameter<String>> allColumnMappings;
1263 06 Sep 05 nicklas 168   
1248 06 Sep 05 nicklas 169   private RequestInformation configurePlugin;
1248 06 Sep 05 nicklas 170   private RequestInformation configureJob;
1248 06 Sep 05 nicklas 171   
1256 06 Sep 05 nicklas 172   private DbControl dc;
1256 06 Sep 05 nicklas 173   private ReporterBatcher batcher;
1256 06 Sep 05 nicklas 174   
1376 22 Sep 05 nicklas 175   /**
1376 22 Sep 05 nicklas 176     Create a new importer.
1376 22 Sep 05 nicklas 177   */
1244 05 Sep 05 nicklas 178   public ReporterFlatFileImporter()
1244 05 Sep 05 nicklas 179   {}
1244 05 Sep 05 nicklas 180   
1244 05 Sep 05 nicklas 181   /*
1244 05 Sep 05 nicklas 182     From the Plugin interface
1244 05 Sep 05 nicklas 183     -------------------------------------------
1244 05 Sep 05 nicklas 184   */
6127 14 Sep 12 nicklas 185   @Override
2512 10 Aug 06 nicklas 186   public boolean supportsConfigurations()
2512 10 Aug 06 nicklas 187   {
2512 10 Aug 06 nicklas 188     return true;
2512 10 Aug 06 nicklas 189   }
6127 14 Sep 12 nicklas 190   @Override
2512 10 Aug 06 nicklas 191   public boolean requiresConfiguration()
2512 10 Aug 06 nicklas 192   {
5241 10 Feb 10 nicklas 193     return false;
2512 10 Aug 06 nicklas 194   }
2722 11 Oct 06 nicklas 195   /**
3596 24 Jul 07 nicklas 196      Request create, write and delete access to Reporter:s, write access to ReporterList:s
2722 11 Oct 06 nicklas 197      and read access to File:s and ReporterType:s.
2722 11 Oct 06 nicklas 198   */
6127 14 Sep 12 nicklas 199   @Override
2722 11 Oct 06 nicklas 200   public Collection<Permissions> getPermissions()
2722 11 Oct 06 nicklas 201   {
2722 11 Oct 06 nicklas 202     if (permissions.size() == 0)
2722 11 Oct 06 nicklas 203     {
3596 24 Jul 07 nicklas 204       permissions.add(new Permissions(Item.REPORTER, null, EnumSet.of(Permission.CREATE, Permission.DELETE)));
2722 11 Oct 06 nicklas 205       permissions.add(new Permissions(Item.REPORTERLIST, null, EnumSet.of(Permission.WRITE)));
2838 31 Oct 06 enell 206       permissions.add(new Permissions(Item.REPORTERTYPE, EnumSet.of(Permission.CREATE, Permission.USE), null));
2722 11 Oct 06 nicklas 207       permissions.add(new Permissions(Item.FILE, null, EnumSet.of(Permission.READ)));
2722 11 Oct 06 nicklas 208     }
2722 11 Oct 06 nicklas 209     return permissions;
2722 11 Oct 06 nicklas 210   }
1376 22 Sep 05 nicklas 211   // -------------------------------------------
1248 06 Sep 05 nicklas 212   
1376 22 Sep 05 nicklas 213   /*
1376 22 Sep 05 nicklas 214     From the InteractivePlugin interface
1376 22 Sep 05 nicklas 215     -------------------------------------------
1376 22 Sep 05 nicklas 216   */
1376 22 Sep 05 nicklas 217   /**
2186 25 Apr 06 nicklas 218     Return a set containing the context:s [REPORTER, LIST],
2186 25 Apr 06 nicklas 219     [REPORTERLIST, ITEM], [REPORTERSCORE, LIST]. The first context
3596 24 Jul 07 nicklas 220     is for importing reporters only, and the last two for importing 
2186 25 Apr 06 nicklas 221     reporters to a reporter list.
1376 22 Sep 05 nicklas 222   */
6127 14 Sep 12 nicklas 223   @Override
1701 09 Dec 05 nicklas 224   public Set<GuiContext> getGuiContexts()
1376 22 Sep 05 nicklas 225   {
1376 22 Sep 05 nicklas 226     return guiContexts;
1376 22 Sep 05 nicklas 227   }
1376 22 Sep 05 nicklas 228   /**
2195 26 Apr 06 nicklas 229     Null if the context is {@link Item#REPORTERLIST} and the
2149 04 Apr 06 nicklas 230     item is a {@link ReporterList}.
3495 14 Jun 07 nicklas 231     @throws PermissionDeniedException If the user doesn't have write permission
3495 14 Jun 07 nicklas 232       to the reporter list
1701 09 Dec 05 nicklas 233   */
6127 14 Sep 12 nicklas 234   @Override
2195 26 Apr 06 nicklas 235   public String isInContext(GuiContext context, Object item)
1701 09 Dec 05 nicklas 236   {
2195 26 Apr 06 nicklas 237     String message =  null;
2195 26 Apr 06 nicklas 238     if (context.getItem() == Item.REPORTERLIST)
2195 26 Apr 06 nicklas 239     {
2195 26 Apr 06 nicklas 240       if (item == null)
2195 26 Apr 06 nicklas 241       {
2195 26 Apr 06 nicklas 242         message = "The object is null";
2195 26 Apr 06 nicklas 243       }
2195 26 Apr 06 nicklas 244       else if (!(item instanceof ReporterList))
2195 26 Apr 06 nicklas 245       {
2195 26 Apr 06 nicklas 246         message = "The object is not a ReporterList: " + item;
2195 26 Apr 06 nicklas 247       }
3495 14 Jun 07 nicklas 248       else
3495 14 Jun 07 nicklas 249       {
3495 14 Jun 07 nicklas 250         ReporterList rl = (ReporterList)item;
3495 14 Jun 07 nicklas 251         rl.checkPermission(Permission.WRITE);
3495 14 Jun 07 nicklas 252       }
2195 26 Apr 06 nicklas 253     }
2195 26 Apr 06 nicklas 254     return message;
1701 09 Dec 05 nicklas 255   }
1701 09 Dec 05 nicklas 256   /**
1376 22 Sep 05 nicklas 257     The {@link Request#COMMAND_CONFIGURE_PLUGIN} command will ask for
1376 22 Sep 05 nicklas 258     parser regular expressions, column mappings and the reporter type.
1376 22 Sep 05 nicklas 259     The {@link Request#COMMAND_CONFIGURE_JOB} command will ask for
1376 22 Sep 05 nicklas 260     a file and if existing reporters should be updated or ignored.
1376 22 Sep 05 nicklas 261   */
6127 14 Sep 12 nicklas 262   @Override
1789 18 Jan 06 nicklas 263   public RequestInformation getRequestInformation(GuiContext context, String command)
1244 05 Sep 05 nicklas 264     throws BaseException
1244 05 Sep 05 nicklas 265   {
1244 05 Sep 05 nicklas 266     RequestInformation requestInformation = null;
1244 05 Sep 05 nicklas 267     if (command.equals(Request.COMMAND_CONFIGURE_PLUGIN))
1244 05 Sep 05 nicklas 268     {
2149 04 Apr 06 nicklas 269       requestInformation = getConfigurePluginParameters(context);
1248 06 Sep 05 nicklas 270     }
1244 05 Sep 05 nicklas 271     else if (command.equals(Request.COMMAND_CONFIGURE_JOB))
1244 05 Sep 05 nicklas 272     {
2149 04 Apr 06 nicklas 273       requestInformation = getConfigureJobParameters(context);
2186 25 Apr 06 nicklas 274       ItemContext fileContext = sc.getCurrentContext(Item.FILE);
5451 26 Oct 10 nicklas 275       fileContext.removeAllTemporaryFilters();
1244 05 Sep 05 nicklas 276     }
1244 05 Sep 05 nicklas 277     return requestInformation;
1244 05 Sep 05 nicklas 278   }
1376 22 Sep 05 nicklas 279   /**
1376 22 Sep 05 nicklas 280     Store configuration settings for {@link Request#COMMAND_CONFIGURE_PLUGIN} and
1376 22 Sep 05 nicklas 281     {@link Request#COMMAND_CONFIGURE_JOB}.
1244 05 Sep 05 nicklas 282   */
6127 14 Sep 12 nicklas 283   @Override
1789 18 Jan 06 nicklas 284   public void configure(GuiContext context, Request request, Response response)
1248 06 Sep 05 nicklas 285   {
1248 06 Sep 05 nicklas 286     String command = request.getCommand();
1248 06 Sep 05 nicklas 287     try
1248 06 Sep 05 nicklas 288     {
1248 06 Sep 05 nicklas 289       if (command.equals(Request.COMMAND_CONFIGURE_PLUGIN))
1248 06 Sep 05 nicklas 290       {
2992 01 Dec 06 enell 291         RequestInformation ri = getConfigurePluginParameters(context);
2992 01 Dec 06 enell 292         List<Throwable> errors = validateRequestParameters(ri.getParameters(), request);
1269 07 Sep 05 nicklas 293         if (errors != null)
1269 07 Sep 05 nicklas 294         {
1269 07 Sep 05 nicklas 295           response.setError(errors.size()+" invalid parameter(s) were found in the request", errors);
1269 07 Sep 05 nicklas 296           return;
1269 07 Sep 05 nicklas 297         }
1269 07 Sep 05 nicklas 298
1248 06 Sep 05 nicklas 299         // Parser settings
1248 06 Sep 05 nicklas 300         storeValue(configuration, request, headerRegexpParameter);
1248 06 Sep 05 nicklas 301         storeValue(configuration, request, dataHeaderRegexpParameter);
1248 06 Sep 05 nicklas 302         storeValue(configuration, request, dataSplitterRegexpParameter);
2203 28 Apr 06 nicklas 303         storeValue(configuration, request, trimQuotesParameter);
1248 06 Sep 05 nicklas 304         storeValue(configuration, request, ignoreRegexpParameter);
1248 06 Sep 05 nicklas 305         storeValue(configuration, request, dataFooterRegexpParameter);
1275 08 Sep 05 nicklas 306         storeValue(configuration, request, minDataColumnsParameter);
1275 08 Sep 05 nicklas 307         storeValue(configuration, request, maxDataColumnsParameter);
4107 29 Jan 08 nicklas 308         storeValue(configuration, request, ri.getParameter(Parameters.CHARSET_PARAMETER));
4107 29 Jan 08 nicklas 309         storeValue(configuration, request, ri.getParameter(Parameters.DECIMAL_SEPARATOR_PARAMETER));
1248 06 Sep 05 nicklas 310         
1248 06 Sep 05 nicklas 311         // Column mappings
3493 14 Jun 07 nicklas 312         storeValue(configuration, request, complexMappings);
3493 14 Jun 07 nicklas 313         boolean allowComplex = "allow".equals(request.getParameterValue(complexMappings.getName()));
5242 11 Feb 10 nicklas 314         for (PluginParameter<String> pp : getAllColumnMappings(false))
1263 06 Sep 05 nicklas 315         {
3493 14 Jun 07 nicklas 316           String mapExpression = (String)request.getParameterValue(pp.getName());
3493 14 Jun 07 nicklas 317           checkColumnMapping(mapExpression, allowComplex, pp.getLabel());
3493 14 Jun 07 nicklas 318           storeValue(configuration, pp, mapExpression);
1263 06 Sep 05 nicklas 319         }
1248 06 Sep 05 nicklas 320         
1248 06 Sep 05 nicklas 321         // Reporter type
1266 07 Sep 05 nicklas 322         storeValue(configuration, request, reporterTypeParameter);
1626 17 Nov 05 nicklas 323         response.setDone("Plugin configuration complete");
1248 06 Sep 05 nicklas 324       }
1248 06 Sep 05 nicklas 325       else if (command.equals(Request.COMMAND_CONFIGURE_JOB))
1248 06 Sep 05 nicklas 326       {
2992 01 Dec 06 enell 327         RequestInformation ri = getConfigureJobParameters(context);
2992 01 Dec 06 enell 328         List<Throwable> errors = validateRequestParameters(ri.getParameters(), request);
1269 07 Sep 05 nicklas 329         if (errors != null)
1269 07 Sep 05 nicklas 330         {
1269 07 Sep 05 nicklas 331           response.setError(errors.size()+" invalid parameter(s) were found in the request", errors);
1269 07 Sep 05 nicklas 332           return;
1269 07 Sep 05 nicklas 333         }
5242 11 Feb 10 nicklas 334         
5242 11 Feb 10 nicklas 335         boolean reporterListContext = context != null && 
5242 11 Feb 10 nicklas 336           (context.getItem() == Item.REPORTERLIST || context.getItem() == Item.REPORTERSCORE);
5242 11 Feb 10 nicklas 337         if (reporterListContext)
2149 04 Apr 06 nicklas 338         {
2149 04 Apr 06 nicklas 339           storeValue(job, request, reporterListParameter);
2149 04 Apr 06 nicklas 340         }
1248 06 Sep 05 nicklas 341         storeValue(job, request, fileParameter);
5241 10 Feb 10 nicklas 342         storeValue(job, request, ri.getParameter("mode"));
5241 10 Feb 10 nicklas 343         
5241 10 Feb 10 nicklas 344         // Parser settings
5241 10 Feb 10 nicklas 345         storeValue(job, request, headerRegexpParameter);
5241 10 Feb 10 nicklas 346         storeValue(job, request, dataHeaderRegexpParameter);
5241 10 Feb 10 nicklas 347         storeValue(job, request, dataSplitterRegexpParameter);
5241 10 Feb 10 nicklas 348         storeValue(job, request, trimQuotesParameter);
5241 10 Feb 10 nicklas 349         storeValue(job, request, ignoreRegexpParameter);
5241 10 Feb 10 nicklas 350         storeValue(job, request, dataFooterRegexpParameter);
5241 10 Feb 10 nicklas 351         storeValue(job, request, minDataColumnsParameter);
5241 10 Feb 10 nicklas 352         storeValue(job, request, maxDataColumnsParameter);
4107 29 Jan 08 nicklas 353         storeValue(job, request, ri.getParameter(Parameters.CHARSET_PARAMETER));
4107 29 Jan 08 nicklas 354         storeValue(job, request, ri.getParameter(Parameters.DECIMAL_SEPARATOR_PARAMETER));
2751 20 Oct 06 nicklas 355         
5241 10 Feb 10 nicklas 356         // Column mappings
5241 10 Feb 10 nicklas 357         storeValue(job, request, complexMappings);
5241 10 Feb 10 nicklas 358         boolean allowComplex = "allow".equals(request.getParameterValue(complexMappings.getName()));
5242 11 Feb 10 nicklas 359         for (PluginParameter<String> pp : getAllColumnMappings(reporterListContext))
5241 10 Feb 10 nicklas 360         {
5241 10 Feb 10 nicklas 361           String mapExpression = (String)request.getParameterValue(pp.getName());
5241 10 Feb 10 nicklas 362           checkColumnMapping(mapExpression, allowComplex, pp.getLabel());
5241 10 Feb 10 nicklas 363           storeValue(job, pp, mapExpression);
5241 10 Feb 10 nicklas 364         }
5241 10 Feb 10 nicklas 365         
2751 20 Oct 06 nicklas 366         // Error handling parameters
2751 20 Oct 06 nicklas 367         storeValue(job, request, defaultErrorParameter);
2751 20 Oct 06 nicklas 368         storeValue(job, request, stringTooLongErrorParameter);
2751 20 Oct 06 nicklas 369         storeValue(job, request, invalidUseOfNullErrorParameter);
2751 20 Oct 06 nicklas 370         storeValue(job, request, numberFormatErrorParameter);
2751 20 Oct 06 nicklas 371         storeValue(job, request, numberOutOfRangeErrorParameter);
3596 24 Jul 07 nicklas 372         storeValue(job, request, reporterIsUsedErrorParameter);
2751 20 Oct 06 nicklas 373         
5480 08 Nov 10 nicklas 374         File importFile = (File)job.getValue(fileParameter.getName());
5480 08 Nov 10 nicklas 375         if (reporterListContext)
5480 08 Nov 10 nicklas 376         {
5480 08 Nov 10 nicklas 377           ReporterList reporterList = (ReporterList)job.getValue("reporterList");
5480 08 Nov 10 nicklas 378           response.setSuggestedJobName("Import reporters to list '" + reporterList.getName()
5480 08 Nov 10 nicklas 379               + "' from '" + importFile.getName() + "'");
5480 08 Nov 10 nicklas 380         }
5480 08 Nov 10 nicklas 381         else
5480 08 Nov 10 nicklas 382         {
5480 08 Nov 10 nicklas 383           response.setSuggestedJobName("Import reporters from '" + importFile.getName() + "'");
5480 08 Nov 10 nicklas 384         }
1626 17 Nov 05 nicklas 385         response.setDone("Job configuration complete", Job.ExecutionTime.SHORT);
1248 06 Sep 05 nicklas 386       }
1248 06 Sep 05 nicklas 387     }
1248 06 Sep 05 nicklas 388     catch (Throwable ex)
1248 06 Sep 05 nicklas 389     {
1248 06 Sep 05 nicklas 390       response.setError(ex.getMessage(), Arrays.asList(ex));
1248 06 Sep 05 nicklas 391     }
1248 06 Sep 05 nicklas 392   }
1376 22 Sep 05 nicklas 393   // -------------------------------------------
1376 22 Sep 05 nicklas 394
1376 22 Sep 05 nicklas 395   /*
1376 22 Sep 05 nicklas 396     From the AbstractFlatFileReporter class
1376 22 Sep 05 nicklas 397     -------------------------------------------
1376 22 Sep 05 nicklas 398   */
2751 20 Oct 06 nicklas 399   private Mapper idMapper;
2751 20 Oct 06 nicklas 400   private Mapper nameMapper;
2751 20 Oct 06 nicklas 401   private Mapper symbolMapper;
2751 20 Oct 06 nicklas 402   private Mapper descriptionMapper;
2751 20 Oct 06 nicklas 403   private Mapper scoreMapper;
2838 31 Oct 06 enell 404   private Mapper reporterTypeMapper;
2751 20 Oct 06 nicklas 405   private Map<ExtendedProperty, Mapper> extendedMappers;
1263 06 Sep 05 nicklas 406   private ReporterType reporterType;
2838 31 Oct 06 enell 407   private Map<String, ReporterType> reporterTypes;
2149 04 Apr 06 nicklas 408   private ReporterList reporterList;
1292 08 Sep 05 nicklas 409   private boolean updateExisting;
4382 07 Aug 08 nicklas 410   private boolean createMissing;
3596 24 Jul 07 nicklas 411   private boolean deleteMode;
1622 16 Nov 05 nicklas 412   private int numInserted;
1622 16 Nov 05 nicklas 413   private int numUpdated;
3474 11 Jun 07 nicklas 414   private int numExists;
2149 04 Apr 06 nicklas 415   private int numAddedToList;
3596 24 Jul 07 nicklas 416   private int numNotFound;
3596 24 Jul 07 nicklas 417   private int numUsed;
3596 24 Jul 07 nicklas 418   private int numDeleted;
2149 04 Apr 06 nicklas 419   private Map<String, Float> deferred;
3596 24 Jul 07 nicklas 420   private Set<String> deleted;
2203 28 Apr 06 nicklas 421   private FlatFileParser ffp;
3472 11 Jun 07 nicklas 422   private boolean nullIfException;
3596 24 Jul 07 nicklas 423   private boolean failIfUsed;
1263 06 Sep 05 nicklas 424   
1270 07 Sep 05 nicklas 425   /**
1376 22 Sep 05 nicklas 426     Create a {@link DbControl} and a {@link ReporterBatcher}. 
1376 22 Sep 05 nicklas 427     Load the {@link ReporterType} if one has been specified.
1270 07 Sep 05 nicklas 428   */
1579 08 Nov 05 enell 429   @Override
2203 28 Apr 06 nicklas 430   protected void begin(FlatFileParser ffp)
1256 06 Sep 05 nicklas 431     throws BaseException
1256 06 Sep 05 nicklas 432   {
2203 28 Apr 06 nicklas 433     super.begin(ffp);
1256 06 Sep 05 nicklas 434     dc = sc.newDbControl();
1256 06 Sep 05 nicklas 435     batcher = ReporterBatcher.getNew(dc);
5242 11 Feb 10 nicklas 436     reporterType = (ReporterType)getJobOrConfigurationValue("reporterType");
2149 04 Apr 06 nicklas 437     reporterList = (ReporterList)job.getValue("reporterList");
4382 07 Aug 08 nicklas 438     String mode = (String)job.getValue("mode");
4447 04 Sep 08 nicklas 439     if (mode == null) mode = "update";
2149 04 Apr 06 nicklas 440     if (reporterList != null) 
2149 04 Apr 06 nicklas 441     {
2149 04 Apr 06 nicklas 442       reporterList = ReporterList.getById(dc, reporterList.getId());
2149 04 Apr 06 nicklas 443       deferred = new HashMap<String, Float>();
2149 04 Apr 06 nicklas 444       numAddedToList = 0;
4382 07 Aug 08 nicklas 445       deleteMode = "remove".equals(mode);
4382 07 Aug 08 nicklas 446       updateExisting = false;
4382 07 Aug 08 nicklas 447       createMissing = false;
2149 04 Apr 06 nicklas 448     }
4382 07 Aug 08 nicklas 449     else
4382 07 Aug 08 nicklas 450     {
4382 07 Aug 08 nicklas 451       updateExisting = "update".equals(mode);
4382 07 Aug 08 nicklas 452       createMissing = updateExisting || "create".equals(mode);
4382 07 Aug 08 nicklas 453       deleteMode = "delete".equals(mode);
4382 07 Aug 08 nicklas 454     }
2203 28 Apr 06 nicklas 455     this.ffp = ffp;
3472 11 Jun 07 nicklas 456     this.nullIfException = "null".equals(job.getValue("numberFormatError"));
7668 21 Mar 19 nicklas 457     ffp.setUseNullIfException(nullIfException);
6870 16 Apr 15 nicklas 458     String reporterIsUsedError = getErrorOption("reporterIsUsedError");
3596 24 Jul 07 nicklas 459     this.failIfUsed = "fail".equals(reporterIsUsedError);
3596 24 Jul 07 nicklas 460     if (reporterIsUsedError != null)
3596 24 Jul 07 nicklas 461     {
3596 24 Jul 07 nicklas 462       addErrorHandler(ItemInUseException.class, new SimpleErrorHandler(!failIfUsed));
3596 24 Jul 07 nicklas 463     }
3596 24 Jul 07 nicklas 464     if (deleteMode)
3596 24 Jul 07 nicklas 465     {
3596 24 Jul 07 nicklas 466       // Keep track of already deleted reporters
3596 24 Jul 07 nicklas 467       deleted = HibernateUtil.getDbEngine().caseInsensitiveComparison() ?
3596 24 Jul 07 nicklas 468         new TreeSet<String>(String.CASE_INSENSITIVE_ORDER) : new HashSet<String>();
3596 24 Jul 07 nicklas 469     }
4076 11 Jan 08 martin 470     if (job.getValue("file") != null)
4076 11 Jan 08 martin 471     {
4076 11 Jan 08 martin 472       batcher.setUpdateSource("File: " + ((File)job.getValue("file")).getName());
4076 11 Jan 08 martin 473     }
1622 16 Nov 05 nicklas 474     numInserted = 0;
1622 16 Nov 05 nicklas 475     numUpdated = 0;
3474 11 Jun 07 nicklas 476     numExists = 0;
1256 06 Sep 05 nicklas 477   }
1248 06 Sep 05 nicklas 478
1270 07 Sep 05 nicklas 479   /**
2203 28 Apr 06 nicklas 480     Initialise column <code>Mapper</code>:s.
2203 28 Apr 06 nicklas 481   */
2203 28 Apr 06 nicklas 482   @Override
2203 28 Apr 06 nicklas 483   protected void beginData()
2203 28 Apr 06 nicklas 484   {
2751 20 Oct 06 nicklas 485     boolean cropStrings = ("crop".equals(job.getValue("stringTooLongError")));
2751 20 Oct 06 nicklas 486     // Mapper that always return null
2751 20 Oct 06 nicklas 487     Mapper nullMapper = new ConstantMapper((String)null);
5243 12 Feb 10 nicklas 488     idMapper = getMapper(ffp, (String)getJobOrConfigurationValue("reporterIdColumnMapping"), 
2751 20 Oct 06 nicklas 489       cropStrings ? ReporterData.MAX_EXTERNAL_ID_LENGTH : null, nullMapper);
3596 24 Jul 07 nicklas 490     if (!deleteMode)
2203 28 Apr 06 nicklas 491     {
5243 12 Feb 10 nicklas 492       nameMapper = getMapper(ffp, (String)getJobOrConfigurationValue("nameColumnMapping"), 
3596 24 Jul 07 nicklas 493         cropStrings ? ReporterData.MAX_NAME_LENGTH : null, null);
5243 12 Feb 10 nicklas 494       symbolMapper = getMapper(ffp, (String)getJobOrConfigurationValue("symbolColumnMapping"), 
3596 24 Jul 07 nicklas 495         cropStrings ? ReporterData.MAX_SYMBOL_LENGTH : null, null);
5243 12 Feb 10 nicklas 496       descriptionMapper = getMapper(ffp, (String)getJobOrConfigurationValue("descriptionColumnMapping"), 
3596 24 Jul 07 nicklas 497         cropStrings ? ReporterData.MAX_DESCRIPTION_LENGTH : null, null);
5243 12 Feb 10 nicklas 498       reporterTypeMapper = getMapper(ffp, (String)getJobOrConfigurationValue("reporterTypeColumnMapping"), 
3596 24 Jul 07 nicklas 499         cropStrings ? ReporterType.MAX_NAME_LENGTH : null, null);
5243 12 Feb 10 nicklas 500       scoreMapper = getMapper(ffp, (String)getJobOrConfigurationValue("scoreColumnMapping"), null, null);
3596 24 Jul 07 nicklas 501       
3596 24 Jul 07 nicklas 502       reporterTypes = new HashMap<String, ReporterType>();
3596 24 Jul 07 nicklas 503       extendedMappers = new HashMap<ExtendedProperty, Mapper>();
3596 24 Jul 07 nicklas 504       List<ExtendedProperty> extendedProperties = ExtendedProperties.getProperties("ReporterData");
3596 24 Jul 07 nicklas 505       if (extendedProperties != null)
2751 20 Oct 06 nicklas 506       {
3596 24 Jul 07 nicklas 507         for (ExtendedProperty ep : extendedProperties)
3596 24 Jul 07 nicklas 508         {
3596 24 Jul 07 nicklas 509           String name = "extendedColumnMapping." + ep.getName();
5243 12 Feb 10 nicklas 510           Mapper m = getMapper(ffp, (String)getJobOrConfigurationValue(name), 
3596 24 Jul 07 nicklas 511             cropStrings && ep.getLength() > 0 ? ep.getLength() : null, null);
3596 24 Jul 07 nicklas 512           if (m != null) extendedMappers.put(ep, m);
3596 24 Jul 07 nicklas 513         }
2751 20 Oct 06 nicklas 514       }
2203 28 Apr 06 nicklas 515     }
2203 28 Apr 06 nicklas 516   }
2203 28 Apr 06 nicklas 517   
2203 28 Apr 06 nicklas 518   /**
1294 08 Sep 05 nicklas 519     Close and commit/rollback the ReporterBatcher and DbControl.
1270 07 Sep 05 nicklas 520   */
1579 08 Nov 05 enell 521   @Override
1294 08 Sep 05 nicklas 522   protected void end(boolean success)
1256 06 Sep 05 nicklas 523     throws BaseException
1256 06 Sep 05 nicklas 524   {
1270 07 Sep 05 nicklas 525     try
1270 07 Sep 05 nicklas 526     {
2149 04 Apr 06 nicklas 527       batcher.flush();
2149 04 Apr 06 nicklas 528       if (reporterList != null)
2149 04 Apr 06 nicklas 529       {
2149 04 Apr 06 nicklas 530         // Add newly inserted reporters to the reporter list
2149 04 Apr 06 nicklas 531         for (Map.Entry<String, Float> entry : deferred.entrySet())
2149 04 Apr 06 nicklas 532         {
2149 04 Apr 06 nicklas 533           ReporterData reporter = batcher.getByExternalId(entry.getKey());
5242 11 Feb 10 nicklas 534           if (reporterList.addReporter(reporter, entry.getValue()))
5242 11 Feb 10 nicklas 535           {
5242 11 Feb 10 nicklas 536             numAddedToList++;
5242 11 Feb 10 nicklas 537           }
2149 04 Apr 06 nicklas 538         }
2149 04 Apr 06 nicklas 539       }
1270 07 Sep 05 nicklas 540       batcher.close();
1294 08 Sep 05 nicklas 541       if (success)
1294 08 Sep 05 nicklas 542       {
1294 08 Sep 05 nicklas 543         dc.commit();
1294 08 Sep 05 nicklas 544       }
1294 08 Sep 05 nicklas 545       else
1294 08 Sep 05 nicklas 546       {
1294 08 Sep 05 nicklas 547         dc.close();
1294 08 Sep 05 nicklas 548       }
1270 07 Sep 05 nicklas 549     }
1270 07 Sep 05 nicklas 550     catch (BaseException ex)
1270 07 Sep 05 nicklas 551     {
1270 07 Sep 05 nicklas 552       dc.close();
1270 07 Sep 05 nicklas 553       throw ex;
1270 07 Sep 05 nicklas 554     }
1270 07 Sep 05 nicklas 555     finally
1270 07 Sep 05 nicklas 556     {
1294 08 Sep 05 nicklas 557       super.end(success);
1270 07 Sep 05 nicklas 558     }
1256 06 Sep 05 nicklas 559   }
1256 06 Sep 05 nicklas 560
1579 08 Nov 05 enell 561   @Override
1244 05 Sep 05 nicklas 562   protected void handleData(FlatFileParser.Data data)
1244 05 Sep 05 nicklas 563     throws BaseException
1244 05 Sep 05 nicklas 564   {
7666 20 Mar 19 nicklas 565     String externalId = idMapper.getString(data);
2751 20 Oct 06 nicklas 566     if (externalId == null) throw new InvalidUseOfNullException("externalId");
1292 08 Sep 05 nicklas 567     ReporterData reporter =  null;
2149 04 Apr 06 nicklas 568     
3596 24 Jul 07 nicklas 569     if (deleteMode)
1256 06 Sep 05 nicklas 570     {
3596 24 Jul 07 nicklas 571       if (deleted.add(externalId))
1292 08 Sep 05 nicklas 572       {
3596 24 Jul 07 nicklas 573         try
3596 24 Jul 07 nicklas 574         {
3596 24 Jul 07 nicklas 575           reporter = batcher.getByExternalId(externalId);
3596 24 Jul 07 nicklas 576         }
3596 24 Jul 07 nicklas 577         catch (ItemNotFoundException ex)
3596 24 Jul 07 nicklas 578         {
3596 24 Jul 07 nicklas 579           numNotFound++;
3596 24 Jul 07 nicklas 580         }
3596 24 Jul 07 nicklas 581         if (reporter != null)
3596 24 Jul 07 nicklas 582         {
3596 24 Jul 07 nicklas 583           if (reporterList != null)
3596 24 Jul 07 nicklas 584           {
3596 24 Jul 07 nicklas 585             reporterList.removeReporter(reporter);
3596 24 Jul 07 nicklas 586             numDeleted++;
3596 24 Jul 07 nicklas 587           }
3596 24 Jul 07 nicklas 588           else
3596 24 Jul 07 nicklas 589           {
3596 24 Jul 07 nicklas 590             try
3596 24 Jul 07 nicklas 591             {
3596 24 Jul 07 nicklas 592               batcher.delete(reporter);
3596 24 Jul 07 nicklas 593               batcher.flushDelete();
3596 24 Jul 07 nicklas 594               numDeleted++;
3596 24 Jul 07 nicklas 595             }
3596 24 Jul 07 nicklas 596             catch (BaseException ex)
3596 24 Jul 07 nicklas 597             {
3596 24 Jul 07 nicklas 598               if (failIfUsed) throw new ItemInUseException("Reporter[externalId=" + externalId + "]", ex);
3596 24 Jul 07 nicklas 599               numUsed++;
3596 24 Jul 07 nicklas 600             }
3596 24 Jul 07 nicklas 601           }
3596 24 Jul 07 nicklas 602         }
1292 08 Sep 05 nicklas 603       }
1292 08 Sep 05 nicklas 604     }
3596 24 Jul 07 nicklas 605     else
1292 08 Sep 05 nicklas 606     {
3596 24 Jul 07 nicklas 607       // Is the reporter already queued for insert?
3596 24 Jul 07 nicklas 608       if (!batcher.isInInsertQueue(externalId))
1263 06 Sep 05 nicklas 609       {
3596 24 Jul 07 nicklas 610         // No, it's not... try to load it from the database
3596 24 Jul 07 nicklas 611         try
2149 04 Apr 06 nicklas 612         {
3596 24 Jul 07 nicklas 613           reporter = batcher.getByExternalId(externalId);
2149 04 Apr 06 nicklas 614         }
3596 24 Jul 07 nicklas 615         catch (ItemNotFoundException ex)
2149 04 Apr 06 nicklas 616         {
3596 24 Jul 07 nicklas 617           // It wasn't in the database either, create a new reporter
4382 07 Aug 08 nicklas 618           numNotFound++;
4382 07 Aug 08 nicklas 619           if (createMissing)
4382 07 Aug 08 nicklas 620           {
4382 07 Aug 08 nicklas 621             reporter = Reporter.getNew(externalId);
4382 07 Aug 08 nicklas 622           }
2149 04 Apr 06 nicklas 623         }
1263 06 Sep 05 nicklas 624       }
3596 24 Jul 07 nicklas 625   
3596 24 Jul 07 nicklas 626       // If we have a reporter object, we must set the properties or add it to a reporter list
3596 24 Jul 07 nicklas 627       if (reporter != null)
1292 08 Sep 05 nicklas 628       {
3596 24 Jul 07 nicklas 629         int currentId = reporter.getId();
3596 24 Jul 07 nicklas 630         if (reporterList != null)
2838 31 Oct 06 enell 631         {
3596 24 Jul 07 nicklas 632           // Add to reporter list
3596 24 Jul 07 nicklas 633           Float score = scoreMapper == null ? 
3596 24 Jul 07 nicklas 634               reporterList.getScore(reporter) : scoreMapper.getFloat(data);
3596 24 Jul 07 nicklas 635           if (currentId == 0)
3596 24 Jul 07 nicklas 636           {
3596 24 Jul 07 nicklas 637             // It is a new reporter, we must wait to add it until the batcher has been flushed
3596 24 Jul 07 nicklas 638             deferred.put(externalId, score);
3596 24 Jul 07 nicklas 639           }
3596 24 Jul 07 nicklas 640           else
3596 24 Jul 07 nicklas 641           {
5242 11 Feb 10 nicklas 642             if (reporterList.addReporter(reporter, score))
5242 11 Feb 10 nicklas 643             {
5242 11 Feb 10 nicklas 644               numAddedToList++;
5242 11 Feb 10 nicklas 645             }
3596 24 Jul 07 nicklas 646           }
2838 31 Oct 06 enell 647         }
2149 04 Apr 06 nicklas 648         
3596 24 Jul 07 nicklas 649         // The actual reporter needs updating or it is a new one
5384 13 Aug 10 nicklas 650         if (updateExisting || currentId == 0)
2149 04 Apr 06 nicklas 651         {
3596 24 Jul 07 nicklas 652           
3596 24 Jul 07 nicklas 653           if (reporterType != null) 
3596 24 Jul 07 nicklas 654           {
3596 24 Jul 07 nicklas 655             Reporter.setReporterType(reporter, reporterType);
3596 24 Jul 07 nicklas 656           }
3596 24 Jul 07 nicklas 657           else if (reporterTypeMapper != null)
3596 24 Jul 07 nicklas 658           {
7666 20 Mar 19 nicklas 659             Reporter.setReporterType(reporter, getReporterType(reporterTypeMapper.getString(data)));
3596 24 Jul 07 nicklas 660           }
7666 20 Mar 19 nicklas 661           String name = nameMapper == null ? reporter.getName() : nameMapper.getString(data);
3596 24 Jul 07 nicklas 662           reporter.setName(name == null ? externalId : name);
3596 24 Jul 07 nicklas 663           
7666 20 Mar 19 nicklas 664           if (symbolMapper != null) reporter.setSymbol(symbolMapper.getString(data));
7666 20 Mar 19 nicklas 665           if (descriptionMapper != null) reporter.setDescription(descriptionMapper.getString(data));
3596 24 Jul 07 nicklas 666           for (Map.Entry<ExtendedProperty, Mapper> entry : extendedMappers.entrySet())
3596 24 Jul 07 nicklas 667           {
3596 24 Jul 07 nicklas 668             ExtendedProperty ep = entry.getKey();
3596 24 Jul 07 nicklas 669             Mapper m = entry.getValue();
7668 21 Mar 19 nicklas 670             reporter.setExtended(ep.getName(), m.getByType(data, ep.getType()));
3596 24 Jul 07 nicklas 671           }
3596 24 Jul 07 nicklas 672           if (currentId != 0)
3596 24 Jul 07 nicklas 673           {
3596 24 Jul 07 nicklas 674             batcher.update(reporter);
3596 24 Jul 07 nicklas 675             numUpdated++;
3596 24 Jul 07 nicklas 676           }
3596 24 Jul 07 nicklas 677           else
3596 24 Jul 07 nicklas 678           {
3596 24 Jul 07 nicklas 679             batcher.insert(reporter);
3596 24 Jul 07 nicklas 680             numInserted++;
3596 24 Jul 07 nicklas 681           }
2149 04 Apr 06 nicklas 682         }
2149 04 Apr 06 nicklas 683         else
2149 04 Apr 06 nicklas 684         {
3596 24 Jul 07 nicklas 685           numExists++;
2149 04 Apr 06 nicklas 686         }
1292 08 Sep 05 nicklas 687       }
1256 06 Sep 05 nicklas 688     }
1244 05 Sep 05 nicklas 689   }
1622 16 Nov 05 nicklas 690   /**
2149 04 Apr 06 nicklas 691     Return <code>x new reporters; y updated reporters; z reporters added to list</code>.
1622 16 Nov 05 nicklas 692   */
6127 14 Sep 12 nicklas 693   @Override
2751 20 Oct 06 nicklas 694   protected String getSuccessMessage(int skippedLines)
1622 16 Nov 05 nicklas 695   {
3596 24 Jul 07 nicklas 696     String msg;
4382 07 Aug 08 nicklas 697     if (reporterList != null)
3596 24 Jul 07 nicklas 698     {
4382 07 Aug 08 nicklas 699       if (deleteMode)
4382 07 Aug 08 nicklas 700       {
4382 07 Aug 08 nicklas 701         msg = numDeleted + " reporter(s) removed from list";
4382 07 Aug 08 nicklas 702       }
4382 07 Aug 08 nicklas 703       else
4382 07 Aug 08 nicklas 704       {
4382 07 Aug 08 nicklas 705         msg = numAddedToList + " reporter(s) added to list";
4382 07 Aug 08 nicklas 706       }
3596 24 Jul 07 nicklas 707       if (numNotFound > 0) msg += "; " + numNotFound + " reporter(s) ignored because they didn't exist";
3596 24 Jul 07 nicklas 708     }
3596 24 Jul 07 nicklas 709     else
3596 24 Jul 07 nicklas 710     {
4382 07 Aug 08 nicklas 711       if (deleteMode)
4382 07 Aug 08 nicklas 712       {
4382 07 Aug 08 nicklas 713         msg = numDeleted + " deleted reporter(s)";
4382 07 Aug 08 nicklas 714         if (numUsed > 0) msg += "; " + numUsed + " reporter(s) are used and could not be deleted";
4382 07 Aug 08 nicklas 715         if (numNotFound > 0) msg += "; " + numNotFound + " reporter(s) ignored because they didn't exist";
4382 07 Aug 08 nicklas 716       }
4382 07 Aug 08 nicklas 717       else
4382 07 Aug 08 nicklas 718       {
4382 07 Aug 08 nicklas 719         msg = numInserted + " new reporter(s)";
4382 07 Aug 08 nicklas 720         if (numUpdated > 0) msg += "; " + numUpdated + " updated reporter(s)";
4382 07 Aug 08 nicklas 721         if (numExists > 0)
4382 07 Aug 08 nicklas 722         {
4382 07 Aug 08 nicklas 723           msg += "; " + numExists + " reporter(s) skipped (already existed)";  
4382 07 Aug 08 nicklas 724         }
4382 07 Aug 08 nicklas 725       }
3596 24 Jul 07 nicklas 726     }
3474 11 Jun 07 nicklas 727     if (skippedLines > 0) msg += "; " + skippedLines + " line(s) skipped due to errors";
3474 11 Jun 07 nicklas 728     return msg;
1622 16 Nov 05 nicklas 729   }
1244 05 Sep 05 nicklas 730   // -------------------------------------------
2149 04 Apr 06 nicklas 731   
5242 11 Feb 10 nicklas 732   private List<PluginParameter<String>> getAllColumnMappings(boolean reporterListContext)
2149 04 Apr 06 nicklas 733   {
2149 04 Apr 06 nicklas 734     if (allColumnMappings == null)
2149 04 Apr 06 nicklas 735     {
2149 04 Apr 06 nicklas 736       // Column mappings
2149 04 Apr 06 nicklas 737       allColumnMappings = new ArrayList<PluginParameter<String>>();
5242 11 Feb 10 nicklas 738       if (reporterListContext)
2149 04 Apr 06 nicklas 739       {
5759 26 Sep 11 nicklas 740         allColumnMappings.add(cloneParameterWithDefaultValue(reporterIdColumnMapping));
5759 26 Sep 11 nicklas 741         allColumnMappings.add(cloneParameterWithDefaultValue(scoreColumnMapping));
5242 11 Feb 10 nicklas 742       }
5242 11 Feb 10 nicklas 743       else
5242 11 Feb 10 nicklas 744       {
5759 26 Sep 11 nicklas 745         allColumnMappings.add(cloneParameterWithDefaultValue(nameColumnMapping));
5759 26 Sep 11 nicklas 746         allColumnMappings.add(cloneParameterWithDefaultValue(reporterIdColumnMapping));
5759 26 Sep 11 nicklas 747         allColumnMappings.add(cloneParameterWithDefaultValue(descriptionColumnMapping));
5759 26 Sep 11 nicklas 748         allColumnMappings.add(cloneParameterWithDefaultValue(symbolColumnMapping));
5759 26 Sep 11 nicklas 749         allColumnMappings.add(cloneParameterWithDefaultValue(reporterTypeColumnMapping));
5242 11 Feb 10 nicklas 750         List<ExtendedProperty> extended = ExtendedProperties.getProperties("ReporterData");
5242 11 Feb 10 nicklas 751         if (extended != null)
2747 19 Oct 06 enell 752         {
5242 11 Feb 10 nicklas 753           for (ExtendedProperty ep : extended)
5242 11 Feb 10 nicklas 754           {
5759 26 Sep 11 nicklas 755             String name = "extendedColumnMapping."+ep.getName();
5242 11 Feb 10 nicklas 756             allColumnMappings.add(
5242 11 Feb 10 nicklas 757               new PluginParameter<String>(
5759 26 Sep 11 nicklas 758                 name,
5242 11 Feb 10 nicklas 759                 ep.getTitle(),
5242 11 Feb 10 nicklas 760                 ep.getDescription(),
5759 26 Sep 11 nicklas 761                 (String)getJobOrConfigurationValue(name),
5242 11 Feb 10 nicklas 762                 optionalColumnMapping
5242 11 Feb 10 nicklas 763                 )
5242 11 Feb 10 nicklas 764               );
5242 11 Feb 10 nicklas 765           }
2747 19 Oct 06 enell 766         }
2149 04 Apr 06 nicklas 767       }
2149 04 Apr 06 nicklas 768     }
2149 04 Apr 06 nicklas 769     return allColumnMappings;
2149 04 Apr 06 nicklas 770   }
2186 25 Apr 06 nicklas 771
2149 04 Apr 06 nicklas 772   private RequestInformation getConfigureJobParameters(GuiContext context)
2149 04 Apr 06 nicklas 773   {
2149 04 Apr 06 nicklas 774     if (configureJob == null)
2149 04 Apr 06 nicklas 775     {
2149 04 Apr 06 nicklas 776       // RequestInformation for CONFIGURE_JOB
2149 04 Apr 06 nicklas 777       List<PluginParameter<?>> parameters = new ArrayList<PluginParameter<?>>();
4382 07 Aug 08 nicklas 778       boolean reporterListContext = context != null && 
4382 07 Aug 08 nicklas 779       (context.getItem() == Item.REPORTERLIST || context.getItem() == Item.REPORTERSCORE);
4382 07 Aug 08 nicklas 780       
4382 07 Aug 08 nicklas 781       if (reporterListContext)
2149 04 Apr 06 nicklas 782       {
2149 04 Apr 06 nicklas 783         ItemParameterType<ReporterList> reporterListType = new ItemParameterType<ReporterList>(ReporterList.class, null, true, 1, null);
2149 04 Apr 06 nicklas 784         reporterListParameter = new PluginParameter<ReporterList>(
2149 04 Apr 06 nicklas 785           "reporterList",
2149 04 Apr 06 nicklas 786           "Reporter list",
2149 04 Apr 06 nicklas 787           "The list to import reporters to",
2149 04 Apr 06 nicklas 788           reporterListType);
2149 04 Apr 06 nicklas 789         parameters.add(reporterListParameter);
2149 04 Apr 06 nicklas 790       }
2149 04 Apr 06 nicklas 791       parameters.add(fileParameter);
3596 24 Jul 07 nicklas 792       
4382 07 Aug 08 nicklas 793       boolean deletePermission = sc.hasPermission(Permission.DELETE, Item.REPORTER);
4382 07 Aug 08 nicklas 794       boolean createPermission = sc.hasPermission(Permission.CREATE, Item.REPORTER);
4382 07 Aug 08 nicklas 795       boolean writePermission = sc.hasPermission(Permission.WRITE, Item.REPORTER);
4382 07 Aug 08 nicklas 796       
3596 24 Jul 07 nicklas 797       List<String> allowedModes = new ArrayList<String>();
4382 07 Aug 08 nicklas 798       String modeDescription = "";
4382 07 Aug 08 nicklas 799       String defaultMode = null;
4382 07 Aug 08 nicklas 800       if (reporterListContext)
3596 24 Jul 07 nicklas 801       {
4382 07 Aug 08 nicklas 802         allowedModes.add("add");
4382 07 Aug 08 nicklas 803         allowedModes.add("remove");
4382 07 Aug 08 nicklas 804         defaultMode = "add";
4382 07 Aug 08 nicklas 805         modeDescription = 
4382 07 Aug 08 nicklas 806           "Select the operating mode of the plug-in. When adding/removing to/from a " +
4382 07 Aug 08 nicklas 807           "reporter list, reporters will not be created or updated.\n\n" +
4382 07 Aug 08 nicklas 808           "add = Add reporters to the reporter list\n" +
4382 07 Aug 08 nicklas 809           "remove = Remove reporter from the reporter list";
3596 24 Jul 07 nicklas 810       }
4382 07 Aug 08 nicklas 811       else 
4382 07 Aug 08 nicklas 812       {
4382 07 Aug 08 nicklas 813         modeDescription = "Select the operating mode of the plug-in.\n\n";
4382 07 Aug 08 nicklas 814         if (createPermission) 
4382 07 Aug 08 nicklas 815         {
4382 07 Aug 08 nicklas 816           allowedModes.add("create");
4382 07 Aug 08 nicklas 817           modeDescription += "create = Only create missing reporters; existing ones are not updated\n";
4382 07 Aug 08 nicklas 818         }
4382 07 Aug 08 nicklas 819         if (writePermission) 
4382 07 Aug 08 nicklas 820         {
4382 07 Aug 08 nicklas 821           allowedModes.add("update");
4382 07 Aug 08 nicklas 822           defaultMode = "update";
4382 07 Aug 08 nicklas 823           modeDescription += "update = Update existing reporters and create missing ones\n";
4382 07 Aug 08 nicklas 824         }
4382 07 Aug 08 nicklas 825         if (deletePermission) 
4382 07 Aug 08 nicklas 826         {
4382 07 Aug 08 nicklas 827           allowedModes.add("delete");
4382 07 Aug 08 nicklas 828           modeDescription += "delete = Delete existing reporters\n";
4382 07 Aug 08 nicklas 829         }
4382 07 Aug 08 nicklas 830       }
3596 24 Jul 07 nicklas 831       StringParameterType modeType = new StringParameterType(255, defaultMode, false, 1, 0, 0, allowedModes);
3596 24 Jul 07 nicklas 832       PluginParameter<String> modeParameter = new PluginParameter<String>(
3596 24 Jul 07 nicklas 833           "mode",
3596 24 Jul 07 nicklas 834           "Mode",
4382 07 Aug 08 nicklas 835           modeDescription,
3596 24 Jul 07 nicklas 836           modeType
3596 24 Jul 07 nicklas 837           );
3596 24 Jul 07 nicklas 838       
3596 24 Jul 07 nicklas 839       parameters.add(modeParameter);
5241 10 Feb 10 nicklas 840       
5241 10 Feb 10 nicklas 841       // Parser regular expressions
5241 10 Feb 10 nicklas 842       parameters.add(parserSection);
5241 10 Feb 10 nicklas 843       parameters.add(cloneParameterWithDefaultValue(headerRegexpParameter));
5241 10 Feb 10 nicklas 844       parameters.add(cloneParameterWithDefaultValue(dataHeaderRegexpParameter));
5241 10 Feb 10 nicklas 845       parameters.add(cloneParameterWithDefaultValue(dataSplitterRegexpParameter));
5241 10 Feb 10 nicklas 846       parameters.add(cloneParameterWithDefaultValue(trimQuotesParameter));
5241 10 Feb 10 nicklas 847       parameters.add(cloneParameterWithDefaultValue(ignoreRegexpParameter));
5241 10 Feb 10 nicklas 848       parameters.add(cloneParameterWithDefaultValue(dataFooterRegexpParameter));
5241 10 Feb 10 nicklas 849       parameters.add(cloneParameterWithDefaultValue(minDataColumnsParameter));
5241 10 Feb 10 nicklas 850       parameters.add(cloneParameterWithDefaultValue(maxDataColumnsParameter));
4107 29 Jan 08 nicklas 851       parameters.add(Parameters.charsetParameter(null, null, 
5242 11 Feb 10 nicklas 852           (String)getJobOrConfigurationValue(Parameters.CHARSET_PARAMETER)));
4107 29 Jan 08 nicklas 853       parameters.add(Parameters.decimalSeparatorParameter(null, null, 
5242 11 Feb 10 nicklas 854           (String)getJobOrConfigurationValue(Parameters.DECIMAL_SEPARATOR_PARAMETER)));
5241 10 Feb 10 nicklas 855
5241 10 Feb 10 nicklas 856       // Column mappings
5241 10 Feb 10 nicklas 857       parameters.add(mappingSection);
5771 29 Sep 11 nicklas 858       parameters.add(cloneParameterWithDefaultValue(complexMappings));
5242 11 Feb 10 nicklas 859       parameters.addAll(getAllColumnMappings(reporterListContext));
2149 04 Apr 06 nicklas 860       
2751 20 Oct 06 nicklas 861       parameters.add(errorSection);
2751 20 Oct 06 nicklas 862       parameters.add(defaultErrorParameter);
2751 20 Oct 06 nicklas 863       parameters.add(stringTooLongErrorParameter);
2751 20 Oct 06 nicklas 864       parameters.add(invalidUseOfNullErrorParameter);
2751 20 Oct 06 nicklas 865       parameters.add(numberFormatErrorParameter);
2751 20 Oct 06 nicklas 866       parameters.add(numberOutOfRangeErrorParameter);
4382 07 Aug 08 nicklas 867       if (!reporterListContext)
4382 07 Aug 08 nicklas 868       {
4382 07 Aug 08 nicklas 869         parameters.add(reporterIsUsedErrorParameter);
4382 07 Aug 08 nicklas 870       }
2149 04 Apr 06 nicklas 871       configureJob = new RequestInformation
2149 04 Apr 06 nicklas 872       (
2149 04 Apr 06 nicklas 873         Request.COMMAND_CONFIGURE_JOB,
2186 25 Apr 06 nicklas 874         "Select a file to import reporters from",
2324 24 May 06 nicklas 875         "Here you select which file to import the reporters from, and if " +
2324 24 May 06 nicklas 876         "existing reporters should be updated or not.",
2149 04 Apr 06 nicklas 877         parameters
2149 04 Apr 06 nicklas 878       );
2149 04 Apr 06 nicklas 879     }
2149 04 Apr 06 nicklas 880     return configureJob;
2149 04 Apr 06 nicklas 881   }
2149 04 Apr 06 nicklas 882   
2149 04 Apr 06 nicklas 883   private RequestInformation getConfigurePluginParameters(GuiContext context)
2149 04 Apr 06 nicklas 884   {
2149 04 Apr 06 nicklas 885     if (configurePlugin == null)
2149 04 Apr 06 nicklas 886     {
2149 04 Apr 06 nicklas 887       // Load reporter types and initialise the reporterTypeParameter
2149 04 Apr 06 nicklas 888       DbControl dc = sc.newDbControl();
2149 04 Apr 06 nicklas 889       ItemQuery<ReporterType> query = ReporterType.getQuery();
2149 04 Apr 06 nicklas 890       query.order(Orders.asc(Hql.property("name")));
2149 04 Apr 06 nicklas 891       List<ReporterType> reporterTypes = new ArrayList<ReporterType>(query.list(dc));
2149 04 Apr 06 nicklas 892       dc.close();
2149 04 Apr 06 nicklas 893       
2149 04 Apr 06 nicklas 894       ItemParameterType<ReporterType> reporterTypeType = new ItemParameterType<ReporterType>(ReporterType.class, null, false, 1, reporterTypes);
2149 04 Apr 06 nicklas 895       reporterTypeParameter = new PluginParameter<ReporterType>(
2149 04 Apr 06 nicklas 896         "reporterType",
2149 04 Apr 06 nicklas 897         "Reporter type",
2149 04 Apr 06 nicklas 898         "The reporter type assigned to the imported reporters",
2149 04 Apr 06 nicklas 899         reporterTypeType);
2149 04 Apr 06 nicklas 900           
2186 25 Apr 06 nicklas 901       // Parameters for CONFIGURE_PLUGIN
2149 04 Apr 06 nicklas 902       List<PluginParameter<?>> parameters = new ArrayList<PluginParameter<?>>();
1244 05 Sep 05 nicklas 903
2149 04 Apr 06 nicklas 904       // Reporter type
2149 04 Apr 06 nicklas 905       parameters.add(reporterTypeParameter);
2149 04 Apr 06 nicklas 906       
2149 04 Apr 06 nicklas 907       // Parser regular expressions
2149 04 Apr 06 nicklas 908       parameters.add(parserSection);
5759 26 Sep 11 nicklas 909       parameters.add(cloneParameterWithDefaultValue(headerRegexpParameter));
5759 26 Sep 11 nicklas 910       parameters.add(cloneParameterWithDefaultValue(dataHeaderRegexpParameter));
5759 26 Sep 11 nicklas 911       parameters.add(cloneParameterWithDefaultValue(dataSplitterRegexpParameter));
5759 26 Sep 11 nicklas 912       parameters.add(cloneParameterWithDefaultValue(trimQuotesParameter));
5759 26 Sep 11 nicklas 913       parameters.add(cloneParameterWithDefaultValue(ignoreRegexpParameter));
5759 26 Sep 11 nicklas 914       parameters.add(cloneParameterWithDefaultValue(dataFooterRegexpParameter));
5759 26 Sep 11 nicklas 915       parameters.add(cloneParameterWithDefaultValue(minDataColumnsParameter));
5759 26 Sep 11 nicklas 916       parameters.add(cloneParameterWithDefaultValue(maxDataColumnsParameter));
5759 26 Sep 11 nicklas 917       parameters.add(Parameters.charsetParameter(null, null, 
5759 26 Sep 11 nicklas 918           (String)getJobOrConfigurationValue(Parameters.CHARSET_PARAMETER)));
5759 26 Sep 11 nicklas 919       parameters.add(Parameters.decimalSeparatorParameter(null, null, 
5759 26 Sep 11 nicklas 920           (String)getJobOrConfigurationValue(Parameters.DECIMAL_SEPARATOR_PARAMETER)));
2149 04 Apr 06 nicklas 921
2149 04 Apr 06 nicklas 922       // Column mappings
2149 04 Apr 06 nicklas 923       parameters.add(mappingSection);
5771 29 Sep 11 nicklas 924       parameters.add(cloneParameterWithDefaultValue(complexMappings));
5242 11 Feb 10 nicklas 925       parameters.addAll(getAllColumnMappings(false));
2149 04 Apr 06 nicklas 926       
2149 04 Apr 06 nicklas 927       configurePlugin = new RequestInformation
2149 04 Apr 06 nicklas 928       (
2149 04 Apr 06 nicklas 929         Request.COMMAND_CONFIGURE_PLUGIN,
2186 25 Apr 06 nicklas 930         "Parser settings",
2186 25 Apr 06 nicklas 931         "Enter the regular expressions used to parse the text file " +
2186 25 Apr 06 nicklas 932         "and the column mappings used to find matching properties for the reporters.",
2149 04 Apr 06 nicklas 933         parameters
2149 04 Apr 06 nicklas 934       );
2149 04 Apr 06 nicklas 935
2149 04 Apr 06 nicklas 936     }
2149 04 Apr 06 nicklas 937     return configurePlugin;
2149 04 Apr 06 nicklas 938   }
2751 20 Oct 06 nicklas 939   
2838 31 Oct 06 enell 940   private ReporterType getReporterType(String name)
2838 31 Oct 06 enell 941   {
2838 31 Oct 06 enell 942     if (name == null)
2838 31 Oct 06 enell 943     {
2838 31 Oct 06 enell 944       return null;
2838 31 Oct 06 enell 945     }
2838 31 Oct 06 enell 946     
2838 31 Oct 06 enell 947     ReporterType rt = reporterTypes.get(name);
2838 31 Oct 06 enell 948     if (rt == null)
2838 31 Oct 06 enell 949     {
2838 31 Oct 06 enell 950       DbControl dc = sc.newDbControl();
2838 31 Oct 06 enell 951       try
2838 31 Oct 06 enell 952       {
2838 31 Oct 06 enell 953         ItemQuery<ReporterType> q = ReporterType.getQuery();
2838 31 Oct 06 enell 954         q.restrict(Restrictions.eq(Hql.property("name"), Expressions.parameter("name", name, Type.STRING)));
2838 31 Oct 06 enell 955         List<ReporterType> rtList = q.list(dc);
2838 31 Oct 06 enell 956         if (rtList.size() == 0)
2838 31 Oct 06 enell 957         {
2838 31 Oct 06 enell 958           rt = ReporterType.getNew(dc);
2838 31 Oct 06 enell 959           rt.setName(name);
2838 31 Oct 06 enell 960           dc.saveItem(rt);
2838 31 Oct 06 enell 961           dc.commit();
2838 31 Oct 06 enell 962           reporterTypes.put(name, rt);
2838 31 Oct 06 enell 963         }
2838 31 Oct 06 enell 964         else 
2838 31 Oct 06 enell 965         {
2838 31 Oct 06 enell 966           rt = rtList.get(0);
2838 31 Oct 06 enell 967         }
2838 31 Oct 06 enell 968       }
2838 31 Oct 06 enell 969       finally
2838 31 Oct 06 enell 970       {
2838 31 Oct 06 enell 971         dc.close();
2838 31 Oct 06 enell 972       }
2838 31 Oct 06 enell 973     }
2838 31 Oct 06 enell 974     return rt;
2838 31 Oct 06 enell 975     
2838 31 Oct 06 enell 976   }
1244 05 Sep 05 nicklas 977 }