src/core/net/sf/basedb/util/overview/validator/DataFileValidator.java

Code
Comments
Other
Rev Date Author Line
4740 05 Feb 09 nicklas 1 /**
4740 05 Feb 09 nicklas 2   $Id$
4740 05 Feb 09 nicklas 3
4740 05 Feb 09 nicklas 4   Copyright (C) 2008 Nicklas Nordborg
4740 05 Feb 09 nicklas 5
4740 05 Feb 09 nicklas 6   This file is part of BASE - BioArray Software Environment.
4740 05 Feb 09 nicklas 7   Available at http://base.thep.lu.se/
4740 05 Feb 09 nicklas 8
4740 05 Feb 09 nicklas 9   BASE is free software; you can redistribute it and/or
4740 05 Feb 09 nicklas 10   modify it under the terms of the GNU General Public License
4740 05 Feb 09 nicklas 11   as published by the Free Software Foundation; either version 3
4740 05 Feb 09 nicklas 12   of the License, or (at your option) any later version.
4740 05 Feb 09 nicklas 13
4740 05 Feb 09 nicklas 14   BASE is distributed in the hope that it will be useful,
4740 05 Feb 09 nicklas 15   but WITHOUT ANY WARRANTY; without even the implied warranty of
4740 05 Feb 09 nicklas 16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
4740 05 Feb 09 nicklas 17   GNU General Public License for more details.
4740 05 Feb 09 nicklas 18
4740 05 Feb 09 nicklas 19   You should have received a copy of the GNU General Public License
4740 05 Feb 09 nicklas 20   along with BASE. If not, see <http://www.gnu.org/licenses/>.
4740 05 Feb 09 nicklas 21 */
4740 05 Feb 09 nicklas 22 package net.sf.basedb.util.overview.validator;
4740 05 Feb 09 nicklas 23
6089 22 Aug 12 nicklas 24 import java.util.Collections;
5721 06 Sep 11 nicklas 25 import java.util.List;
5721 06 Sep 11 nicklas 26
4740 05 Feb 09 nicklas 27 import net.sf.basedb.core.BasicItem;
4740 05 Feb 09 nicklas 28 import net.sf.basedb.core.DataFileType;
4740 05 Feb 09 nicklas 29 import net.sf.basedb.core.DbControl;
4740 05 Feb 09 nicklas 30 import net.sf.basedb.core.File;
5721 06 Sep 11 nicklas 31 import net.sf.basedb.core.FileSet;
4740 05 Feb 09 nicklas 32 import net.sf.basedb.core.FileSetMember;
4740 05 Feb 09 nicklas 33 import net.sf.basedb.core.FileStoreEnabled;
4750 11 Feb 09 nicklas 34 import net.sf.basedb.core.ItemQuery;
5721 06 Sep 11 nicklas 35 import net.sf.basedb.core.ItemSubtype;
5721 06 Sep 11 nicklas 36 import net.sf.basedb.core.ItemSubtypeFileType;
4740 05 Feb 09 nicklas 37 import net.sf.basedb.core.PermissionDeniedException;
4750 11 Feb 09 nicklas 38 import net.sf.basedb.core.Platform;
4750 11 Feb 09 nicklas 39 import net.sf.basedb.core.PlatformFileType;
4750 11 Feb 09 nicklas 40 import net.sf.basedb.core.PlatformVariant;
6959 01 Oct 15 nicklas 41 import net.sf.basedb.core.RootRawBioAssay;
5721 06 Sep 11 nicklas 42 import net.sf.basedb.core.Subtypable;
5721 06 Sep 11 nicklas 43 import net.sf.basedb.core.UsableDataFileType;
4750 11 Feb 09 nicklas 44 import net.sf.basedb.core.query.Expressions;
4750 11 Feb 09 nicklas 45 import net.sf.basedb.core.query.Hql;
4750 11 Feb 09 nicklas 46 import net.sf.basedb.core.query.Restrictions;
4740 05 Feb 09 nicklas 47 import net.sf.basedb.util.overview.Fix;
4740 05 Feb 09 nicklas 48 import net.sf.basedb.util.overview.OverviewContext;
4740 05 Feb 09 nicklas 49 import net.sf.basedb.util.overview.Validator;
4740 05 Feb 09 nicklas 50 import net.sf.basedb.util.overview.Node;
4740 05 Feb 09 nicklas 51
4740 05 Feb 09 nicklas 52 /**
4740 05 Feb 09 nicklas 53   Validator implementation for data files. The node containing
4740 05 Feb 09 nicklas 54   the data files is expected to live in a folder-type node that
4740 05 Feb 09 nicklas 55   has a {@link FileStoreEnabled} item as it's parent (if there 
4740 05 Feb 09 nicklas 56   are more than one file) or as an immediate child node to
4740 05 Feb 09 nicklas 57   it's parent item (if there is only one file).
4740 05 Feb 09 nicklas 58   Validation rules:
4740 05 Feb 09 nicklas 59   <ul>
4740 05 Feb 09 nicklas 60   <li>Denied access to file: {@link Validator#DENIED_FILE}
4740 05 Feb 09 nicklas 61   <li>Denied access to file type: {@link Validator#DENIED_DATAFILETYPE}
4740 05 Feb 09 nicklas 62   <li>File is not a valid file: {@link Validator#DATAFILE_INVALID}
4740 05 Feb 09 nicklas 63   <li>File has not been validated: {@link Validator#DATAFILE_NOTVALIDATED}
4740 05 Feb 09 nicklas 64   <li>File type doesn't match parent item type: {@link Validator#DATAFILE_INVALID_ITEM}
4750 11 Feb 09 nicklas 65   <li>File type is not part of used platform: {@link Validator#DATAFILE_NOTPLATFORM}
5721 06 Sep 11 nicklas 66   <li>Too many files of a single-file file type: {@link Validator#DATAFILE_TOOMANYFILES}
4750 11 Feb 09 nicklas 67   <li>Missing a required file: {@link Validator#MISSING_DATAFILE}
4740 05 Feb 09 nicklas 68   </ul>
4740 05 Feb 09 nicklas 69   
4740 05 Feb 09 nicklas 70   @author Nicklas
4740 05 Feb 09 nicklas 71   @version 2.10
4740 05 Feb 09 nicklas 72   @base.modified $Date$
4740 05 Feb 09 nicklas 73 */
4740 05 Feb 09 nicklas 74 public class DataFileValidator
4740 05 Feb 09 nicklas 75   extends BasicNodeValidator<FileSetMember>
4740 05 Feb 09 nicklas 76 {
4740 05 Feb 09 nicklas 77   
4740 05 Feb 09 nicklas 78   public DataFileValidator()
4740 05 Feb 09 nicklas 79   {
4740 05 Feb 09 nicklas 80     super(null, null);
4740 05 Feb 09 nicklas 81   }
4740 05 Feb 09 nicklas 82   
4740 05 Feb 09 nicklas 83   /*
4740 05 Feb 09 nicklas 84     From BasicNodeValidator class
4740 05 Feb 09 nicklas 85     -----------------------------
4740 05 Feb 09 nicklas 86   */
4740 05 Feb 09 nicklas 87   @Override
4740 05 Feb 09 nicklas 88   public void postValidate(DbControl dc, OverviewContext context, Node node, Node parentNode)
4740 05 Feb 09 nicklas 89   {
4740 05 Feb 09 nicklas 90     super.postValidate(dc, context, node, parentNode);
4750 11 Feb 09 nicklas 91     FileSetMember member = (FileSetMember)node.getItem(dc);
4740 05 Feb 09 nicklas 92     // The parent node is either a folder (if we have more than one file)
4740 05 Feb 09 nicklas 93     // or the actual parent (for a single file)
6959 01 Oct 15 nicklas 94     BasicItem parentItem = parentNode.getNodeType() == Node.Type.FOLDER ? 
6959 01 Oct 15 nicklas 95         parentNode.getParent().getItem(dc) : parentNode.getItem(dc);
6959 01 Oct 15 nicklas 96     if (parentItem instanceof RootRawBioAssay)
6959 01 Oct 15 nicklas 97     {
6959 01 Oct 15 nicklas 98       // The parent may be a root raw bioasay if the overview starts at the
6959 01 Oct 15 nicklas 99       // experiment level
6959 01 Oct 15 nicklas 100       parentItem = ((RootRawBioAssay)parentItem).getRawBioAssay();
6959 01 Oct 15 nicklas 101     }
6959 01 Oct 15 nicklas 102     FileStoreEnabled fileStoreItem = (FileStoreEnabled)parentItem;
4740 05 Feb 09 nicklas 103     
4740 05 Feb 09 nicklas 104     // Check that we have access to the file and it's file type
4740 05 Feb 09 nicklas 105     DataFileType fileType = null;
4740 05 Feb 09 nicklas 106     File file = null;
4740 05 Feb 09 nicklas 107     try
4740 05 Feb 09 nicklas 108     {
4740 05 Feb 09 nicklas 109       fileType = member.getDataFileType();
4740 05 Feb 09 nicklas 110     }
4740 05 Feb 09 nicklas 111     catch (PermissionDeniedException ex)
4740 05 Feb 09 nicklas 112     {}
4740 05 Feb 09 nicklas 113     try
4740 05 Feb 09 nicklas 114     {
4740 05 Feb 09 nicklas 115       file = member.getFile();
4740 05 Feb 09 nicklas 116     }
4740 05 Feb 09 nicklas 117     catch (PermissionDeniedException ex)
4740 05 Feb 09 nicklas 118     {}
4740 05 Feb 09 nicklas 119     if (fileType == null)
4740 05 Feb 09 nicklas 120     {
4740 05 Feb 09 nicklas 121       context.createFailure(Validator.DENIED_DATAFILETYPE, node, null);
4740 05 Feb 09 nicklas 122     }
4740 05 Feb 09 nicklas 123     if (file == null)
4740 05 Feb 09 nicklas 124     {
4740 05 Feb 09 nicklas 125       context.createFailure(Validator.DENIED_FILE, node, null);
4740 05 Feb 09 nicklas 126     }
4740 05 Feb 09 nicklas 127     
4740 05 Feb 09 nicklas 128     // Check if a validator has determined that the file IS invalid
4740 05 Feb 09 nicklas 129     if (Boolean.FALSE.equals(member.isValid()))
4740 05 Feb 09 nicklas 130     {
4740 05 Feb 09 nicklas 131       String errorMsg = fileType == null ? "Data file " : fileType.getName();
4740 05 Feb 09 nicklas 132       errorMsg += " is not valid: " + member.getErrorMessage();
4740 05 Feb 09 nicklas 133       context.createFailure(Validator.DATAFILE_INVALID, node, errorMsg,
6959 01 Oct 15 nicklas 134         new Fix("Select another file", parentItem, member)
4740 05 Feb 09 nicklas 135       );
4740 05 Feb 09 nicklas 136     }
4740 05 Feb 09 nicklas 137     
4740 05 Feb 09 nicklas 138     if (fileType != null)
4740 05 Feb 09 nicklas 139     {
4740 05 Feb 09 nicklas 140       // Check if the file hasn't been validated even if a validator exists
5623 06 May 11 nicklas 141       if (fileType.hasActiveValidator(dc) && member.isValid() == null)
4740 05 Feb 09 nicklas 142       {
4740 05 Feb 09 nicklas 143         context.createFailure(Validator.DATAFILE_NOTVALIDATED, node, 
4740 05 Feb 09 nicklas 144           fileType.getName() + " has not been validated", 
6959 01 Oct 15 nicklas 145           new Fix("Validate the file / Select another file", parentItem, member));
4740 05 Feb 09 nicklas 146       }
4740 05 Feb 09 nicklas 147
4740 05 Feb 09 nicklas 148       // Check that the file type is matching the parent item's type
4740 05 Feb 09 nicklas 149       if (fileType.getItemType() != parentItem.getType())
4740 05 Feb 09 nicklas 150       {
4740 05 Feb 09 nicklas 151         context.createFailure(Validator.DATAFILE_INVALID_ITEM, node, 
4740 05 Feb 09 nicklas 152           "Data file '" + fileType.getName() + "' can't be used on item type: " + parentItem.getType(), 
6959 01 Oct 15 nicklas 153           new Fix("Remove file", parentItem, member)
4740 05 Feb 09 nicklas 154         );
4740 05 Feb 09 nicklas 155       }
4750 11 Feb 09 nicklas 156
5721 06 Sep 11 nicklas 157       // Check that the file type is part of the used platform/variant/subtype
4750 11 Feb 09 nicklas 158       try
4750 11 Feb 09 nicklas 159       {
6959 01 Oct 15 nicklas 160         Platform platform = fileStoreItem.getPlatform();
6959 01 Oct 15 nicklas 161         PlatformVariant variant = fileStoreItem.getVariant();
4750 11 Feb 09 nicklas 162         if (platform != null)
4750 11 Feb 09 nicklas 163         {
4750 11 Feb 09 nicklas 164           // The item to apply fixes on, variant or platform
4750 11 Feb 09 nicklas 165           String pvName = null;
4750 11 Feb 09 nicklas 166           BasicItem pvItem = null;
4750 11 Feb 09 nicklas 167           if (variant != null)
4750 11 Feb 09 nicklas 168           {
4750 11 Feb 09 nicklas 169             pvItem = variant;
4750 11 Feb 09 nicklas 170             pvName = variant.getName();
4750 11 Feb 09 nicklas 171           }
4750 11 Feb 09 nicklas 172           else
4750 11 Feb 09 nicklas 173           {
4750 11 Feb 09 nicklas 174             pvItem = platform;
4750 11 Feb 09 nicklas 175             pvName = platform.getName();
4750 11 Feb 09 nicklas 176           }
5721 06 Sep 11 nicklas 177           if (platform.getFileType(fileType, variant, false) == null)
4750 11 Feb 09 nicklas 178           {
4750 11 Feb 09 nicklas 179             context.createFailure(Validator.DATAFILE_NOTPLATFORM, node, 
4750 11 Feb 09 nicklas 180                 fileType.getName() + " can't be used with '" + pvName + "' platform", 
4750 11 Feb 09 nicklas 181                 new Fix("Remove '" + fileType.getName() + "' from " + parentItem.getType().toString().toLowerCase(), 
6960 01 Oct 15 nicklas 182                   parentItem, fileType),
4750 11 Feb 09 nicklas 183                 new Fix("Add '" + fileType.getName() +"' to '" + pvName + "' platform", pvItem, fileType)
4750 11 Feb 09 nicklas 184               );
4750 11 Feb 09 nicklas 185           }
4750 11 Feb 09 nicklas 186         }
5721 06 Sep 11 nicklas 187         else if (parentItem instanceof Subtypable)
5721 06 Sep 11 nicklas 188         {
5721 06 Sep 11 nicklas 189           ItemSubtype subtype = ((Subtypable)parentItem).getItemSubtype();
5721 06 Sep 11 nicklas 190           if (subtype != null)
5721 06 Sep 11 nicklas 191           {
5721 06 Sep 11 nicklas 192             if (subtype.getAssociatedDataFileType(fileType, false) == null)
5721 06 Sep 11 nicklas 193             {
5721 06 Sep 11 nicklas 194               context.createFailure(Validator.DATAFILE_NOTPLATFORM, node, 
5721 06 Sep 11 nicklas 195                   fileType.getName() + " can't be used with '" + subtype.getName() + "' subtype", 
5721 06 Sep 11 nicklas 196                   new Fix("Remove '" + fileType.getName() + "' from " + parentItem.getType().toString().toLowerCase(), 
6960 01 Oct 15 nicklas 197                     parentItem, fileType),
5721 06 Sep 11 nicklas 198                   new Fix("Add '" + fileType.getName() +"' to '" + subtype.getName() + "' subtype", subtype, fileType)
5721 06 Sep 11 nicklas 199                 );
5721 06 Sep 11 nicklas 200             }
5721 06 Sep 11 nicklas 201           }
5721 06 Sep 11 nicklas 202         }
4750 11 Feb 09 nicklas 203       }
4750 11 Feb 09 nicklas 204       catch (PermissionDeniedException ex)
4750 11 Feb 09 nicklas 205       {}    
4740 05 Feb 09 nicklas 206     }
4740 05 Feb 09 nicklas 207   }
4740 05 Feb 09 nicklas 208   
4740 05 Feb 09 nicklas 209   /**
4740 05 Feb 09 nicklas 210     @return Always "null"
4740 05 Feb 09 nicklas 211   */
4740 05 Feb 09 nicklas 212   @Override
5651 08 Jun 11 nicklas 213   protected Fix getMissingItemFix(DbControl dc, Node parentNode)
4740 05 Feb 09 nicklas 214   {
4740 05 Feb 09 nicklas 215     return null;
4740 05 Feb 09 nicklas 216   }
4750 11 Feb 09 nicklas 217
4750 11 Feb 09 nicklas 218   @Override
4750 11 Feb 09 nicklas 219   public void postValidateFolder(DbControl dc, OverviewContext context, 
4750 11 Feb 09 nicklas 220       Node folderNode, Node parentNode)
4740 05 Feb 09 nicklas 221   {
4750 11 Feb 09 nicklas 222     super.postValidateFolder(dc, context, folderNode, parentNode);
6959 01 Oct 15 nicklas 223     BasicItem parentItem = parentNode.getItem(dc);
6959 01 Oct 15 nicklas 224     if (parentItem instanceof RootRawBioAssay)
6959 01 Oct 15 nicklas 225     {
6959 01 Oct 15 nicklas 226       // The parent may be a root raw bioasay if the overview starts at the
6959 01 Oct 15 nicklas 227       // experiment level
6959 01 Oct 15 nicklas 228       parentItem = ((RootRawBioAssay)parentItem).getRawBioAssay();
6959 01 Oct 15 nicklas 229     }
6959 01 Oct 15 nicklas 230     FileStoreEnabled fileStoreItem = (FileStoreEnabled)parentItem;
4740 05 Feb 09 nicklas 231     
4750 11 Feb 09 nicklas 232     // Check that we have linked a file for all file types that
5721 06 Sep 11 nicklas 233     // are required by the platform and that the multiplicity setting
5721 06 Sep 11 nicklas 234     // is ok
4750 11 Feb 09 nicklas 235     try
4740 05 Feb 09 nicklas 236     {
6959 01 Oct 15 nicklas 237       Platform platform = fileStoreItem.getPlatform();
6959 01 Oct 15 nicklas 238       PlatformVariant variant = fileStoreItem.getVariant();
5721 06 Sep 11 nicklas 239       BasicItem pvItem = null;
5721 06 Sep 11 nicklas 240       ItemSubtype subtype = parentItem instanceof Subtypable ? 
5721 06 Sep 11 nicklas 241           ((Subtypable)parentItem).getItemSubtype() : null;
5721 06 Sep 11 nicklas 242       // List for holding all file types defined by the platform or subtype
6089 22 Aug 12 nicklas 243       List<? extends UsableDataFileType> fileTypes = Collections.emptyList();
5721 06 Sep 11 nicklas 244       if (platform != null)
4740 05 Feb 09 nicklas 245       {
5721 06 Sep 11 nicklas 246         pvItem = variant != null ? variant : platform;
5721 06 Sep 11 nicklas 247         // Create a query that returns all required platform file types
5721 06 Sep 11 nicklas 248         ItemQuery<PlatformFileType> query = platform.getFileTypes(variant, variant == null);
5721 06 Sep 11 nicklas 249         query.join(Hql.innerJoin("dataFileType", "dft"));
5721 06 Sep 11 nicklas 250         query.restrict(
5721 06 Sep 11 nicklas 251           Restrictions.eq(
5721 06 Sep 11 nicklas 252             Hql.property("dft", "itemType"), 
6959 01 Oct 15 nicklas 253             Expressions.integer(parentItem.getType().getValue())
5721 06 Sep 11 nicklas 254           )
5721 06 Sep 11 nicklas 255         );
5721 06 Sep 11 nicklas 256         fileTypes = query.list(dc);
4740 05 Feb 09 nicklas 257       }
5721 06 Sep 11 nicklas 258       if (subtype != null)
4740 05 Feb 09 nicklas 259       {
5721 06 Sep 11 nicklas 260         pvItem = subtype;
5721 06 Sep 11 nicklas 261         // Create a query that returns all required subtype file types
5721 06 Sep 11 nicklas 262         ItemQuery<ItemSubtypeFileType> query = subtype.getDataFileTypes();
5721 06 Sep 11 nicklas 263         query.join(Hql.innerJoin("dataFileType", "dft"));
5721 06 Sep 11 nicklas 264         query.restrict(
5721 06 Sep 11 nicklas 265           Restrictions.eq(
5721 06 Sep 11 nicklas 266             Hql.property("dft", "itemType"), 
6959 01 Oct 15 nicklas 267             Expressions.integer(parentItem.getType().getValue())
5721 06 Sep 11 nicklas 268           )
5721 06 Sep 11 nicklas 269         );
5721 06 Sep 11 nicklas 270         fileTypes = query.list(dc);
4740 05 Feb 09 nicklas 271       }
6959 01 Oct 15 nicklas 272       FileSet fs = fileStoreItem.hasFileSet() ? fileStoreItem.getFileSet() : null;
5721 06 Sep 11 nicklas 273       for (UsableDataFileType fileType : fileTypes)
5721 06 Sep 11 nicklas 274       {
5721 06 Sep 11 nicklas 275         DataFileType dft = fileType.getDataFileType();
5721 06 Sep 11 nicklas 276         int numMembers = fs == null ? 0 : fs.getNumMembers(dft);
5721 06 Sep 11 nicklas 277         if (fileType.isRequired() && numMembers == 0)
5721 06 Sep 11 nicklas 278         {
5721 06 Sep 11 nicklas 279           context.createFailure(Validator.MISSING_DATAFILE, parentNode, 
5721 06 Sep 11 nicklas 280               "Missing '" + dft.getName() + "'", 
5721 06 Sep 11 nicklas 281               new Fix("Add '" + dft.getName() + "' to " + parentItem.getType().toString().toLowerCase(), 
6960 01 Oct 15 nicklas 282                   parentItem, dft),
5721 06 Sep 11 nicklas 283               new Fix("Remove 'Required' flag from '" + dft.getName() + "'", pvItem, dft)
5721 06 Sep 11 nicklas 284             );
5721 06 Sep 11 nicklas 285         }
5721 06 Sep 11 nicklas 286         if (!fileType.getAllowMultiple() && numMembers > 1)
5721 06 Sep 11 nicklas 287         {
5721 06 Sep 11 nicklas 288           context.createFailure(Validator.DATAFILE_TOOMANYFILES, parentNode, 
5721 06 Sep 11 nicklas 289               "Too many files: '" + dft.getName() + "'", 
5721 06 Sep 11 nicklas 290               new Fix("Remove '" + dft.getName() + "' from " + parentItem.getType().toString().toLowerCase(), 
6960 01 Oct 15 nicklas 291                   parentItem, dft),
5721 06 Sep 11 nicklas 292               new Fix("Check 'Allow multiple files' on '" + dft.getName() + "'", pvItem, dft)
5721 06 Sep 11 nicklas 293             );
5721 06 Sep 11 nicklas 294         }
5721 06 Sep 11 nicklas 295       }
4740 05 Feb 09 nicklas 296     }
4750 11 Feb 09 nicklas 297     catch (PermissionDeniedException ex)
4750 11 Feb 09 nicklas 298     {}
4740 05 Feb 09 nicklas 299   }
4750 11 Feb 09 nicklas 300   // ----------------------------
4750 11 Feb 09 nicklas 301     
4740 05 Feb 09 nicklas 302 }