Changeset 5713


Ignore:
Timestamp:
Sep 2, 2011, 3:01:58 PM (10 years ago)
Author:
Nicklas Nordborg
Message:

References #1604: Support for multiple files of the same type in a FileSet?

Added data and core layer classes. Started with the gui and seems to work when adding single files of a type. There are some remaining things to implement when used with multiple files. File validation is not yet fully functional. Some of the batch importers need to be fixed as well to be able to handle multiple files of the same type.

Location:
trunk
Files:
3 added
38 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/clients/web/net/sf/basedb/clients/web/Base.java

    r5698 r5713  
    3232import net.sf.basedb.core.File;
    3333import net.sf.basedb.core.FileSet;
     34import net.sf.basedb.core.FileSetMember;
    3435import net.sf.basedb.core.FileStoreEnabled;
    3536import net.sf.basedb.core.ItemSubtype;
     
    11081109    if (subtype != null)
    11091110    {
    1110       onSubtype = Restrictions.eq(Hql.alias("its"), Hql.entity(subtype));
    1111       q.join(Hql.leftJoin("itemSubtypes", "its"));
     1111      onSubtype = Restrictions.eq(Hql.property("its", "itemSubtype.id"), Hql.entity(subtype));
     1112      q.join(Hql.leftJoin(null, "itemSubtypes", "its", onSubtype, false));
    11121113    }
    11131114   
     
    11291130    q.restrict(full);
    11301131    q.order(Orders.asc(Hql.property("name")));
    1131     q.setCacheResult(true);
     1132    q.setDistinct(true);
    11321133    return q;
    11331134  }
     
    14671468      if (param.startsWith("datafile."))
    14681469      {
     1470        /*
    14691471        int dataFileTypeId = Values.getInt(param.substring(9));
    14701472        DataFileType dft = DataFileType.getById(dc, dataFileTypeId);
     
    14731475        if (filePath == null)
    14741476        {
    1475           fileSet.removeMember(dft);
     1477          // TODO #1604
     1478//          fileSet.removeMember(dft);
    14761479        }
    14771480        else
     
    14841487          }
    14851488        }
     1489        */
     1490      }
     1491      else if (param.startsWith("setfile."))
     1492      {
     1493        int dataFileTypeId = Values.getInt(param.substring(8));
     1494        int fileId = Values.getInt(request.getParameter(param));
     1495        DataFileType dft = DataFileType.getById(dc, dataFileTypeId);
     1496        File file = fileId == 0 ? null : File.getById(dc, fileId);
     1497        if (fileSet == null) fileSet = item.getFileSet();
     1498        fileSet.setMember(file, dft);
     1499        if (cc != null && file != null)
     1500        {
     1501          cc.setRecent(file, dft.getExternalId(), maxRecent);
     1502        }
     1503      }
     1504      else if (param.startsWith("addfile."))
     1505      {
     1506        int dataFileTypeId = Values.getInt(param.substring(8));
     1507        Integer[] fileId = Values.getInt(request.getParameterValues(param));
     1508        DataFileType dft = DataFileType.getById(dc, dataFileTypeId);
     1509        if (fileSet == null) fileSet = item.getFileSet();
     1510        for (Integer id : fileId)
     1511        {
     1512          File file = File.getById(dc, id);
     1513          fileSet.addMember(file, dft);
     1514          if (cc != null)
     1515          {
     1516            cc.setRecent(file, dft.getExternalId(), maxRecent);
     1517          }
     1518        }
     1519      }
     1520      else if (param.startsWith("removefile."))
     1521      {
     1522        FileSetMember member = FileSetMember.getById(dc, Values.getInt(request.getParameter(param)));
     1523        if (fileSet == null) fileSet = item.getFileSet();
     1524        fileSet.removeMember(member);
    14861525      }
    14871526    }
  • trunk/src/core/net/sf/basedb/core/FileSet.java

    r5689 r5713  
    2525import java.util.Collections;
    2626import java.util.HashSet;
     27import java.util.Iterator;
    2728import java.util.LinkedList;
    2829import java.util.List;
    29 import java.util.Map;
    3030import java.util.Set;
    3131
     
    3737import net.sf.basedb.core.data.FileSetData;
    3838import net.sf.basedb.core.data.FileSetMemberData;
    39 import net.sf.basedb.core.data.DataFileTypeData;
    4039import net.sf.basedb.util.extensions.ClientContext;
    4140import net.sf.basedb.util.extensions.ExtensionsInvoker;
     
    281280 
    282281  /**
     282    Get a query that returns all members in a file set with a specific
     283    {@link DataFileType}.
     284   
     285    @param type The type of the file
     286    @return A query returning <code>FileSetMember</code> items
     287    @since 3.0
     288  */
     289  public ItemQuery<FileSetMember> getMembers(DataFileType type)
     290  {
     291    ItemQuery<FileSetMember> query = getMembers();
     292    query.restrictPermanent(
     293      Restrictions.eq(
     294        Hql.property("dataFileType"),
     295        Hql.entity(type)
     296      )
     297    );
     298    return query;
     299  }
     300
     301 
     302  /**
    283303    Set a file of a given type as a member of this file set.
    284     If another file of the given type already exists, it is replaced
    285     with this file. If no member exists, a new entry is created and
    286     automatically saved to the database when {@link DbControl#commit()}
    287     is called.
    288     @param file The file to set as a member
     304    If one ore more files of the given type already exists, they are
     305    replaced with this file. If no member exists, a new entry is created
     306    and automatically saved to the database when {@link DbControl#commit()}
     307    is called. Calling this method is equivalent to first call
     308    {@link #removeAllOfType(DataFileType)} and then {@link
     309    #addMember(File, DataFileType)}.
     310   
     311    @param file The file to set as a member (or null to remove it)
    289312    @param type The type of the file
    290313    @return The new FileSetMember item
     
    296319  public FileSetMember setMember(File file, DataFileType type)
    297320  {
     321    // Permission checks must be done first so we don't disrupt internal state
     322    checkPermission(Permission.WRITE);
     323    if (type == null) throw new InvalidUseOfNullException("type");
     324    if (type.getItemType() != getItemType())
     325    {
     326      throw new InvalidDataException("File type '" + type.getName() +
     327        "' can't be used on " + getItemType());
     328    }
     329    if (file != null) file.checkPermission(Permission.USE);
     330
     331    removeAllOfType(type);
     332    return file == null ? null : addMember(file, type);
     333  }
     334 
     335  /**
     336    Add a file as a member to the file set.
     337   
     338    @param file The file to add
     339    @param type The type of the file
     340    @return The new FileSetMember item
     341    @throws InvalidUseOfNullException If file or type is null
     342    @throws PermissionDeniedException If the logged in user doesn't
     343      have write permission for this file set or use permission for the
     344      file
     345    @since 3.0
     346  */
     347  public FileSetMember addMember(File file, DataFileType type)
     348  {
    298349    checkPermission(Permission.WRITE);
    299350    if (file == null) throw new InvalidUseOfNullException("file");
     
    305356    }
    306357    file.checkPermission(Permission.USE);
    307    
    308     Map<DataFileTypeData, FileSetMemberData> members = getData().getMembers();
    309     FileSetMemberData memberData = members.get(type.getData());
    310     FileSetMember member = null;
    311     if (memberData == null)
    312     {
    313       member = FileSetMember.getNew(getDbControl(), this, file, type);
    314       members.put(type.getData(), member.getData());
    315       getDbControl().saveItemIf(this, member, false);
    316     }
    317     else
    318     {
    319       member = getDbControl().getItem(FileSetMember.class, memberData);
    320       if (!file.getData().equals(memberData.getFile()))
    321       {
    322         // The file has changed -- reset metadata
    323         memberData.setFile(file.getData());
    324         memberData.setValid(null);
    325         memberData.setErrorMessage(null);
    326        
    327         // Create context and invoke the extensions system
    328         ExtensionsInvoker<ValidationAction> invoker = getInvoker(getDbControl());
    329        
    330         // Reset the metadata
    331         invoker.render(new ResetMetadataRenderer(Collections.singletonList(new ValidatingFileSetMember(member))));
    332       }
    333     }
     358
     359    // Create new member entry
     360    FileSetMember member = FileSetMember.getNew(getDbControl(), this, file, type);
     361    getData().getMembers().add(member.getData());
     362    getDbControl().saveItemIf(this, member, false);
    334363    return member;
    335364  }
    336365 
    337366  /**
    338     Check if the file set contains a file of the specified type.
     367    Check if the file set contains at least one file of the specified type.
    339368    @param type A <code>DataFileType</code> object
    340369    @return TRUE if the file set contains a file of
     
    344373  {
    345374    if (type == null) return false;
    346     return getData().getMembers().containsKey(type.getData());
    347   }
    348 
    349   /**
    350     Get the member of the given type.
     375    int typeId = type.getId();
     376    for (FileSetMemberData member : getData().getMembers())
     377    {
     378      if (member.getDataFileType().getId() == typeId) return true;
     379    }
     380    return false;
     381  }
     382 
     383  /**
     384    Get the number of members in the file set of the specified type.
     385    @param type A <code>DataFileType</code> object
     386    @return The number of files in the file set with the given type
     387   */
     388  public int getNumMembers(DataFileType type)
     389  {
     390    if (type == null) return 0;
     391    int typeId = type.getId();
     392    int numMembers = 0;
     393    for (FileSetMemberData member : getData().getMembers())
     394    {
     395      if (member.getDataFileType().getId() == typeId) numMembers++;
     396    }
     397    return numMembers; 
     398  }
     399
     400  /**
     401    Get the member of the given type assuming that there
     402    is only a single member of that type. If there is
     403    more than one member of the given type, it is undefined
     404    which file that is returned.
     405   
    351406    @param type A <code>DataFileType</code> object
    352407    @return A FileSetMember object or null if no member
    353408      of the specified type exists
    354409  */
     410  @Deprecated
    355411  public FileSetMember getMember(DataFileType type)
    356412  {
    357413    if (type == null) return null;
    358     FileSetMemberData member = getData().getMembers().get(type.getData());
    359     if (member == null) return null;
    360     return getDbControl().getItem(FileSetMember.class, member);
    361   }
    362  
    363   /**
    364     Remove the member of the given type.
     414    int typeId = type.getId();
     415    for (FileSetMemberData member : getData().getMembers())
     416    {
     417      if (member.getDataFileType().getId() == typeId)
     418      {
     419        return getDbControl().getItem(FileSetMember.class, member);
     420      }
     421    }
     422    return null;
     423  }
     424 
     425  /**
     426    Remove the given member from this file set.
     427    @param member The member to remove
     428    @since 3.0
     429  */
     430  public void removeMember(FileSetMember member)
     431  {
     432    checkPermission(Permission.WRITE);
     433    if (member == null) throw new InvalidUseOfNullException("member");
     434    if (getData().getMembers().remove(member.getData()))
     435    {
     436      DbControl dc = getDbControl();
     437      dc.deleteItem(member);
     438      // Create context and invoke the extensions system
     439      ExtensionsInvoker<ValidationAction> invoker = getInvoker(dc);
     440     
     441      // Reset the metadata
     442      invoker.render(new ResetMetadataRenderer(Collections.singletonList(new ValidatingFileSetMember(member))));
     443    }
     444  }
     445 
     446  /**
     447    Remove all member files of the given type.
    365448
    366449    @param type A <code>DataFileType</code> object
     
    368451    @throws PermissionDeniedException If the logged in user
    369452      doesn't have write permission for this file set
    370   */
    371   public void removeMember(DataFileType type)
     453    @return The number of removed files
     454    @since 3.0
     455  */
     456  public int removeAllOfType(DataFileType type)
    372457  {
    373458    checkPermission(Permission.WRITE);
    374459    if (type == null) throw new InvalidUseOfNullException("type");
    375     FileSetMemberData member = getData().getMembers().remove(type.getData());
    376     if (member != null)
    377     {
    378       DbControl dc = getDbControl();
    379       FileSetMember m = dc.getItem(FileSetMember.class, member);
    380       dc.deleteItem(m);
    381      
     460    DbControl dc = getDbControl();
     461    int typeId = type.getId();
     462    Iterator<FileSetMemberData> it = getData().getMembers().iterator();
     463    // Keep track of removed members so that we can invoke metadata extensions
     464    List<ValidatingFileSetMember> removed = new ArrayList<ValidatingFileSetMember>();
     465    while (it.hasNext())
     466    {
     467      FileSetMemberData member = it.next();
     468      if (member.getDataFileType().getId() == typeId)
     469      {
     470        it.remove();
     471        FileSetMember m = dc.getItem(FileSetMember.class, member);
     472        dc.deleteItem(m);
     473        removed.add(new ValidatingFileSetMember(m));
     474      }
     475    }
     476    if (removed.size() > 0)
     477    {
    382478      // Create context and invoke the extensions system
    383479      ExtensionsInvoker<ValidationAction> invoker = getInvoker(dc);
    384480     
    385481      // Reset the metadata
    386       invoker.render(new ResetMetadataRenderer(Collections.singletonList(new ValidatingFileSetMember(m))));
    387     }
     482      invoker.render(new ResetMetadataRenderer(removed));
     483    }
     484    return removed.size();
    388485  }
    389486 
     
    400497    DbControl dc = getDbControl();
    401498    List<ValidatingFileSetMember> members = new ArrayList<ValidatingFileSetMember>(getData().getMembers().size());
    402     for (FileSetMemberData memberData : getData().getMembers().values())
     499    for (FileSetMemberData memberData : getData().getMembers())
    403500    {
    404501      FileSetMember member = dc.getItem(FileSetMember.class, memberData);
     
    449546    PlatformVariant variant = item.getVariant();
    450547    if (platform == null) return true;
    451    
     548
     549    // Load all required file types
    452550    ItemQuery<PlatformFileType> query = platform.getFileTypes(variant, variant == null);
    453551    query.restrict(
     
    457555      )
    458556    );
    459    
    460     Set<DataFileTypeData> memberTypes = getData().getMembers().keySet();
    461     for (PlatformFileType pft : query.list(getDbControl()))
    462     {
    463       if (!memberTypes.contains(pft.getData().getDataFileType()))
     557    List<PlatformFileType> allRequired = query.list(getDbControl());
     558    if (allRequired.size() == 0) return true;
     559   
     560    // Load ID of all member types
     561    Set<Integer> memberTypes = new HashSet<Integer>();
     562    for (FileSetMemberData member : getData().getMembers())
     563    {
     564      memberTypes.add(member.getDataFileType().getId());
     565    }
     566   
     567    // Check each required type
     568    for (PlatformFileType pft : allRequired)
     569    {
     570      if (!memberTypes.contains(pft.getData().getDataFileType().getId()))
    464571      {
    465572        return false;
     
    492599    );
    493600
    494     Set<DataFileTypeData> memberTypes = getData().getMembers().keySet();
    495     Set<Integer> memberIds = new HashSet<Integer>(memberTypes.size());
    496     for (DataFileTypeData member : memberTypes)
    497     {
    498       memberIds.add(member.getId());
     601    Set<Integer> memberIds = new HashSet<Integer>();
     602    for (FileSetMemberData member : getData().getMembers())
     603    {
     604      memberIds.add(member.getDataFileType().getId());
    499605    }
    500606    // Ignore all platform file types that we already have
     
    544650    // Load all members of the file set
    545651    List<ValidatingFileSetMember> members = new ArrayList<ValidatingFileSetMember>(getData().getMembers().size());
    546     for (FileSetMemberData memberData : getData().getMembers().values())
     652    for (FileSetMemberData memberData : getData().getMembers())
    547653    {
    548654      FileSetMember member = dc.getItem(FileSetMember.class, memberData);
  • trunk/src/core/net/sf/basedb/core/FileSetMember.java

    r4750 r5713  
    230230    PlatformVariant variant = item.getVariant();
    231231    if (platform == null) return false;
    232     return platform.getFileType(getDataFileType(), variant) != null;
     232    return platform.getFileType(getDataFileType(), variant, false) != null;
    233233  }
    234234
  • trunk/src/core/net/sf/basedb/core/FileStoreUtil.java

    r5630 r5713  
    2323package net.sf.basedb.core;
    2424
     25import java.util.ArrayList;
    2526import java.util.LinkedList;
    2627import java.util.List;
    2728
    2829import net.sf.basedb.core.data.DataFileTypeData;
    29 import net.sf.basedb.core.data.FileData;
    3030import net.sf.basedb.core.data.FileSetMemberData;
    3131import net.sf.basedb.core.query.Expressions;
     
    8686  /**
    8787    Get the file of the given data file type in the
    88     {@link FileStoreEnabled} item's file set.
     88    {@link FileStoreEnabled} item's file set assuming that at most
     89    one file exists.
    8990   
    9091    @param dc DbControl used to access the database.
     
    9394    @param requireValid TRUE to only get the data file if is a valid or unvalidated
    9495      file
    95     @return The file item, or null if no (valid) file of the given type exists
     96    @return A file item, or null if no (valid) file of the given type exists
    9697    @throws PermissionDeniedException If the logged in user doesn't have
    9798      read permission to the file
     
    100101  public static File getDataFile(DbControl dc, FileStoreEnabled item, String dataFileType, boolean requireValid)
    101102  {
    102     FileData file = null;
    103103    if (item != null && item.hasFileSet())
    104104    {
     
    107107      query.setString("externalId", dataFileType);
    108108      DataFileTypeData dft = HibernateUtil.loadData(DataFileTypeData.class, query);
    109       FileSetMemberData member = item.getFileSet().getData().getMembers().get(dft);
    110       if (member != null)
     109      if (dft != null)
    111110      {
    112         if (!requireValid || !Boolean.FALSE.equals(member.isValid()))
     111        int typeId = dft.getId();
     112        for (FileSetMemberData member : item.getFileSet().getData().getMembers())
    113113        {
    114           file = member.getFile();
     114          if (member.getDataFileType().getId() == typeId)
     115          {
     116            if (!requireValid || !Boolean.FALSE.equals(member.isValid()))
     117            {
     118              return dc.getItem(File.class, member.getFile());
     119            }
     120          }
    115121        }
    116122      }
    117123    }
    118     return file == null ? null : dc.getItem(File.class, file);
     124    return null;
     125  }
     126
     127 
     128  /**
     129    Get the file of the given data file type in the
     130    {@link FileStoreEnabled} item's file set.
     131   
     132    @param dc DbControl used to access the database.
     133    @param item The {@link FileStoreEnabled} item to check
     134    @param dataFileType The external ID of the {@link DataFileType} to check for
     135    @param requireValid TRUE to only get the data file if is a valid or unvalidated
     136      file
     137    @return A list with file items, empty if no (valid) file of the given type exists
     138    @throws PermissionDeniedException If the logged in user doesn't have
     139      read permission to the file
     140    @since 3.0
     141  */
     142  public static List<File> getDataFiles(DbControl dc, FileStoreEnabled item, String dataFileType, boolean requireValid)
     143  {
     144    List<File> files = new ArrayList<File>();
     145    if (item != null && item.hasFileSet())
     146    {
     147      org.hibernate.Query query = HibernateUtil.getPredefinedQuery(
     148        dc.getHibernateSession(), "GET_DATAFILETYPE_FOR_EXTERNAL_ID");
     149      query.setString("externalId", dataFileType);
     150      DataFileTypeData dft = HibernateUtil.loadData(DataFileTypeData.class, query);
     151      if (dft != null)
     152      {
     153        int typeId = dft.getId();
     154        for (FileSetMemberData member : item.getFileSet().getData().getMembers())
     155        {
     156          if (member.getDataFileType().getId() == typeId)
     157          {
     158            if (!requireValid || !Boolean.FALSE.equals(member.isValid()))
     159            {
     160              files.add(dc.getItem(File.class, member.getFile()));
     161            }
     162          }
     163        }
     164      }
     165    }
     166    return files;
    119167  }
    120168 
     
    174222    if (file == null)
    175223    {
    176       fileSet.removeMember(type);
     224      // TODO #1604
     225//      fileSet.removeMember(type);
    177226    }
    178227    else
     
    230279    if (file == null)
    231280    {
    232       fileSet.removeMember(type);
     281      // TODO #1604
     282//      fileSet.removeMember(type);
    233283    }
    234284    else
  • trunk/src/core/net/sf/basedb/core/Install.java

    r5709 r5713  
    3333import net.sf.basedb.core.data.HardwareData;
    3434import net.sf.basedb.core.data.ItemSubtypeData;
     35import net.sf.basedb.core.data.ItemSubtypeFileTypeData;
    3536import net.sf.basedb.core.data.MimeTypeData;
    3637import net.sf.basedb.core.data.PlatformData;
     
    864865        DataFileType.SAM, "Sequence Alignment/Map",
    865866        "SAM format is a generic format for storing large nucleotide sequence alignments.",
    866         Item.DERIVEDBIOASSAY, "sam", alignedType, assembly
     867        Item.DERIVEDBIOASSAY, "sam", alignedType, new ItemSubtypeFT(assembly, false, false)
    867868      );
    868869      DataFileTypeData bamFile = createDataFileType(
    869870        DataFileType.BAM, "Compressed Sequence Alignment/Map",
    870871        "BAM format is a BGZF-compressed SAM file.",
    871         Item.DERIVEDBIOASSAY, "bam", alignedType, assembly
     872        Item.DERIVEDBIOASSAY, "bam", alignedType, new ItemSubtypeFT(assembly, false, false)
    872873      );
    873874      DataFileTypeData scanImageFile = createDataFileType(
    874875        DataFileType.MICROARRAY_IMAGE, "Microarray image",
    875876        "Scanned image from a microarray slide.",
    876         Item.DERIVEDBIOASSAY, "tif", imageType, scan
     877        Item.DERIVEDBIOASSAY, "tif", imageType, new ItemSubtypeFT(scan, false, true)
    877878      );
    878879     
     
    882883      createPlatform("generic", "Generic", "Generic platform which expects data to be imported into the database",
    883884        false, null, 0,
    884         new PlatformFT(reporterMapFile, false),
    885         new PlatformFT(printMapFile, false),
    886         new PlatformFT(rawDataFile, false)
     885        new PlatformFT(reporterMapFile, false, false),
     886        new PlatformFT(printMapFile, false, false),
     887        new PlatformFT(rawDataFile, false, true)
    887888      );
    888889      createPlatform("affymetrix", "Affymetrix", "Affymetrix platform", true, null, 1,
    889         new PlatformFT(celFile, true),
    890         new PlatformFT(cdfFile, true)
     890        new PlatformFT(celFile, true, false),
     891        new PlatformFT(cdfFile, true, false)
    891892      );
    892893     
     
    25912592            platformFile.setDataFileType(pft.fileType);
    25922593            platformFile.setRequired(pft.required);
     2594            platformFile.setAllowMultiple(pft.multiple);
    25932595            HibernateUtil.saveData(session, platformFile);
    25942596          }
     
    26142616    String externalId, String name, String description,
    26152617    Item itemType, String extension, ItemSubtypeData genericType,
    2616     ItemSubtypeData... itemSubtypes)
     2618    ItemSubtypeFT... itemSubtypes)
    26172619    throws BaseException
    26182620  {
     
    26362638        if (itemSubtypes != null)
    26372639        {
    2638           for (ItemSubtypeData itemSubtype : itemSubtypes)
     2640          if (itemSubtypes != null)
    26392641          {
    2640             fileType.getItemSubtypes().add(itemSubtype);
     2642            for (ItemSubtypeFT sft : itemSubtypes)
     2643            {
     2644              ItemSubtypeFileTypeData subtypeFile = new ItemSubtypeFileTypeData();
     2645              subtypeFile.setItemSubtype(sft.subtype);
     2646              subtypeFile.setDataFileType(fileType);
     2647              subtypeFile.setRequired(sft.required);
     2648              subtypeFile.setAllowMultiple(sft.multiple);
     2649              HibernateUtil.saveData(session, subtypeFile);
     2650            }
    26412651          }
    26422652        }
     
    26522662        fileType.setExtension(extension);
    26532663        fileType.setGenericType(genericType);
     2664        HibernateUtil.saveData(session, fileType);
    26542665 
    26552666        if (itemSubtypes != null)
    26562667        {
    2657           for (ItemSubtypeData itemSubtype : itemSubtypes)
     2668          for (ItemSubtypeFT sft : itemSubtypes)
    26582669          {
    2659             fileType.getItemSubtypes().add(itemSubtype);
     2670            ItemSubtypeFileTypeData subtypeFile = new ItemSubtypeFileTypeData();
     2671            subtypeFile.setItemSubtype(sft.subtype);
     2672            subtypeFile.setDataFileType(fileType);
     2673            subtypeFile.setRequired(sft.required);
     2674            subtypeFile.setAllowMultiple(sft.multiple);
     2675            HibernateUtil.saveData(session, subtypeFile);
    26602676          }
    26612677        }
    26622678       
    2663         HibernateUtil.saveData(session, fileType);
    26642679        HibernateUtil.commit(tx);
    26652680        log.info("createDataFileType: OK [externalId="+externalId+"]");
     
    26982713  private static class PlatformFT
    26992714  {
    2700     private final DataFileTypeData fileType;
    2701     private final boolean required;
     2715    final DataFileTypeData fileType;
     2716    final boolean required;
     2717    final boolean multiple;
    27022718   
    2703     private PlatformFT(DataFileTypeData fileType, boolean required)
     2719    PlatformFT(DataFileTypeData fileType, boolean required, boolean multiple)
    27042720    {
    27052721      this.fileType = fileType;
    27062722      this.required = required;
    2707     }
    2708   }
    2709  
     2723      this.multiple = multiple;
     2724    }
     2725  }
     2726
     2727  private static class ItemSubtypeFT
     2728  {
     2729    final ItemSubtypeData subtype;
     2730    final boolean required;
     2731    final boolean multiple;
     2732   
     2733    ItemSubtypeFT(ItemSubtypeData subtype, boolean required, boolean multiple)
     2734    {
     2735      this.subtype = subtype;
     2736      this.required = required;
     2737      this.multiple = multiple;
     2738    }
     2739  }
     2740
    27102741}
  • trunk/src/core/net/sf/basedb/core/Item.java

    r5703 r5713  
    220220  ITEMSUBTYPE(145, "Item subtype", "ist", ItemSubtype.class, ItemSubtypeData.class, DefinedPermissions.basic,
    221221      1510),
    222    
     222  /**
     223    The item is a {@link PlatformFileType}
     224  */
     225  ITEMSUBTYPEFILETYPE(352, "Item subtype file type", "sft", ItemSubtypeFileType.class, ItemSubtypeFileTypeData.class, null,
     226    960),
     227
    223228  /**
    224229    The item is a {@link Reporter}.
  • trunk/src/core/net/sf/basedb/core/ItemSubtype.java

    r5698 r5713  
    3232
    3333import net.sf.basedb.core.data.ItemSubtypeData;
     34import net.sf.basedb.core.data.ItemSubtypeFileTypeData;
    3435import net.sf.basedb.core.data.SubtypableData;
    3536import net.sf.basedb.core.query.Expressions;
     
    531532    @return A query
    532533  */
    533   public ItemQuery<DataFileType> getDataFileTypes()
    534   {
    535     ItemQuery<DataFileType> query = DataFileType.getQuery();
    536     query.joinPermanent(Hql.innerJoin("itemSubtypes", Item.ITEMSUBTYPE.getAlias()));
    537     query.restrictPermanent(
    538       Restrictions.eq(
    539         Hql.alias(Item.ITEMSUBTYPE.getAlias()),
    540         Hql.entity(this)
    541     ));
     534  public ItemQuery<ItemSubtypeFileType> getDataFileTypes()
     535  {
     536    ItemQuery<ItemSubtypeFileType> query = ItemSubtypeFileType.getQuery(this);
    542537    return query;
    543538  }
     
    550545  public boolean isAssociatedDataFileType(DataFileType fileType)
    551546  {
    552     return getData().getDataFileTypes().contains(fileType.getData());
    553   }
    554  
    555   /**
    556     Add a data file type as an associated file type. The data file type
    557     must use the same main item type as this subtype.
    558     @param fileType The file type to associate (required)
    559   */
    560   public void addAssociatedDataFileType(DataFileType fileType)
     547    return getData().getFileTypes().containsKey(fileType.getData());
     548  }
     549 
     550  /**
     551    Get information about a data file type that has been associated with this
     552    item subtype. The data file type must use the same main item type as this subtype.
     553   
     554    @param fileType The file type to get information for
     555    @param create If TRUE, the file type will be added to the subtype if it doesn't already exists
     556    @return Null if the file type isn't registered with the subtype (and create is false)
     557      or a {@link ItemSubtypeFileType} object
     558  */
     559  public ItemSubtypeFileType getAssociatedDataFileType(DataFileType fileType, boolean create)
    561560  {
    562561    checkPermission(Permission.WRITE);
    563562    if (fileType == null) throw new InvalidUseOfNullException("fileType");
    564     if (fileType.getItemType() != getMainItemType())
    565     {
    566       throw new InvalidDataException("The file type is not used for " + getMainItemType() + ": " + fileType.getName());
    567     }
    568     getData().getDataFileTypes().add(fileType.getData());
     563   
     564    ItemSubtypeFileType sf = null;
     565    ItemSubtypeFileTypeData sfData = getData().getFileTypes().get(fileType.getData());
     566    if (sfData != null)
     567    {
     568      sf = getDbControl().getItem(ItemSubtypeFileType.class, sfData);
     569    }
     570    else if (create)
     571    {
     572      if (fileType.getItemType() != getMainItemType())
     573      {
     574        throw new InvalidDataException("The file type is not used for " + getMainItemType() + ": " + fileType.getName());
     575      }
     576      sf = ItemSubtypeFileType.getNew(getDbControl(), this, fileType);
     577      getData().getFileTypes().put(fileType.getData(), sf.getData());
     578      getDbControl().saveItemIf(this, sf, false);
     579    }
     580    return sf;
    569581  }
    570582 
     
    577589  {
    578590    checkPermission(Permission.WRITE);
    579     if (fileType != null)
    580     {
    581       getData().getDataFileTypes().remove(fileType.getData());
     591    if (getData().getFileTypes().containsKey(fileType.getData()))
     592    {
     593      ItemSubtypeFileTypeData sfData = getData().getFileTypes().remove(fileType.getData());
     594      DbControl dc = getDbControl();
     595      ItemSubtypeFileType sf = dc.getItem(ItemSubtypeFileType.class, sfData);
     596      dc.deleteItem(sf);
    582597    }
    583598  }
  • trunk/src/core/net/sf/basedb/core/Platform.java

    r5574 r5713  
    457457 
    458458  /**
    459     Add a file type to this platform/variant. If the file type has
    460     already been registered this method can be used to change the
    461     <code>required</code> flag.
    462    
    463     @param type The file type
    464     @param required If a file of this type is required or not
    465     @param variant An optional variant
    466     @throws PermissionDeniedException If the logged in user doesn't
    467       have write permission
    468     @throws InvalidUseOfNullException If type is null
    469   */
    470   public void addFileType(DataFileType type, boolean required, PlatformVariant variant)
    471   {
    472     checkPermission(Permission.WRITE);
    473     if (type == null) throw new InvalidUseOfNullException("type");
    474     FileTypeIndex index = new FileTypeIndex(variant == null ? null : variant.getData(), type.getData());
    475     if (!getData().getFileTypes().containsKey(index))
    476     {
    477       PlatformFileType platformFileType =
    478         PlatformFileType.getNew(getDbControl(), this, variant, type, required);
    479       getData().getFileTypes().put(index, platformFileType.getData());
    480       getDbControl().saveItemIf(this, platformFileType, false);
    481     }
    482     else
    483     {
    484       PlatformFileTypeData pfData = getData().getFileTypes().get(index);
    485       pfData.setRequired(required);
    486     }
    487   }
    488  
    489   /**
    490459    Remove a file type from this platform/variant. If the file
    491460    type isn't registered this method does nothing. If a variant is given
     
    508477    {
    509478      PlatformFileTypeData pfData = getData().getFileTypes().remove(index);
    510       if (pfData != null)
    511       {
    512         DbControl dc = getDbControl();
    513         PlatformFileType pf = dc.getItem(PlatformFileType.class, pfData);
    514         dc.deleteItem(pf);
    515       }
     479      DbControl dc = getDbControl();
     480      PlatformFileType pf = dc.getItem(PlatformFileType.class, pfData);
     481      dc.deleteItem(pf);
    516482    }
    517483  }
     
    523489    @param type The file type to get information for
    524490    @param variant An optional variant
    525     @return Null if the file type isn't registered with the platform/variant
     491    @param create If TRUE, the file type will be added to the platform if it doesn't already exists
     492    @return Null if the file type isn't registered with the platform/variant (and create is false)
    526493      or a {@link PlatformFileType} object
    527   */
    528   public PlatformFileType getFileType(DataFileType type, PlatformVariant variant)
     494    @since 3.0
     495  */
     496  public PlatformFileType getFileType(DataFileType type, PlatformVariant variant, boolean create)
    529497  {
    530498    if (type == null) throw new InvalidUseOfNullException("type");
     
    534502    {
    535503      PlatformFileTypeData pfData = getData().getFileTypes().get(index);
    536       if (pfData != null)
    537       {
    538         DbControl dc = getDbControl();
    539         pf = dc.getItem(PlatformFileType.class, pfData);
    540       }
     504      pf = getDbControl().getItem(PlatformFileType.class, pfData);
     505    }
     506    else if (create)
     507    {
     508      pf = PlatformFileType.getNew(getDbControl(), this, variant, type);
     509      getData().getFileTypes().put(index, pf.getData());
     510      getDbControl().saveItemIf(this, pf, false);
    541511    }
    542512    return pf;
  • trunk/src/core/net/sf/basedb/core/PlatformFileType.java

    r4517 r5713  
    3737public class PlatformFileType
    3838  extends BasicChildItem<PlatformFileTypeData>
     39  implements UsableDataFileType
    3940{
    4041 
     
    5960    @param variant The variant (optional)
    6061    @param fileType The file type
    61     @param required If files of this type are required when using the platform or no
    6262  */
    6363  static PlatformFileType getNew(DbControl dc, Platform platform, PlatformVariant variant,
    64     DataFileType fileType, boolean required)
     64    DataFileType fileType)
    6565  {
    6666    PlatformFileType type = dc.newItem(PlatformFileType.class);
     
    6969    data.setVariant(variant == null ? null : variant.getData());
    7070    data.setDataFileType(fileType.getData());
    71     data.setRequired(required);
    7271    return type;
    7372  }
     
    222221    @return A file set member type item
    223222  */
     223  @Override
    224224  public DataFileType getDataFileType()
    225225  {
     
    234234    use {@link FileSet#hasAllRequiredFiles()}.
    235235  */
     236  @Override
    236237  public boolean isRequired()
    237238  {
    238239    return getData().isRequired();
    239240  }
     241  /**
     242    Set the required flag for this file type.
     243  */
     244  public void setRequired(boolean required)
     245  {
     246    checkPermission(Permission.WRITE);
     247    getData().setRequired(required);
     248  }
     249 
     250  /**
     251    Check if more than one file of this type is allowed in a file set or not.
     252    Note! The requirement is not enforced by the core. It should be used as a
     253    hint to client applications so they can create a proper GUI.
     254  */
     255  @Override
     256  public boolean getAllowMultiple()
     257  {
     258    return getData().getAllowMultiple();
     259  }
     260 
     261  /**
     262    Allow or disallow multiple files of this file type in a file set.
     263  */
     264  public void setAllowMultiple(boolean multiple)
     265  {
     266    checkPermission(Permission.WRITE);
     267    getData().setAllowMultiple(multiple);
     268  }
    240269
    241270}
  • trunk/src/core/net/sf/basedb/core/PlatformVariant.java

    r5574 r5713  
    450450  }
    451451 
    452   /**
    453     Add a file type to this platform variant. If the file type has
    454     already been registered this method does nothing.
    455     @param type The file type
    456     @param required TRUE if this file type should be required by the platform, FALSE otherwise.
    457     @throws PermissionDeniedException If the logged in user doesn't
    458       have write permission to the platform
    459     @throws InvalidUseOfNullException If type is null
    460     @see Platform#addFileType(DataFileType, boolean, PlatformVariant)
    461   */
    462   public void addFileType(DataFileType type, boolean required)
    463   {
    464     getPlatform().addFileType(type, required, this);
    465   }
    466 
    467   /**
    468     Remove a file type from this platform variant. If the file
    469     type isn't registered this method does nothing.
    470    
    471     @param type The file type to remove
    472     @throws PermissionDeniedException If the logged in user doesn't
    473       have write permission to the platform
    474     @throws InvalidUseOfNullException If type is null
    475     @see Platform#removeFileType(DataFileType, PlatformVariant)
    476   */
    477   public void removeFileType(DataFileType type)
    478   {
    479     getPlatform().removeFileType(type, this);
    480   }
     452
    481453}
  • trunk/src/core/net/sf/basedb/core/data/DataFileTypeData.java

    r5698 r5713  
    2222package net.sf.basedb.core.data;
    2323
    24 import java.util.HashSet;
    2524import java.util.Set;
    2625
     
    139138  }
    140139 
    141   private Set<ItemSubtypeData> itemSubtypes;
     140  private Set<ItemSubtypeFileTypeData> itemSubtypes;
    142141  /**
    143142    The subtypes that this file type can be used with.
    144143
    145     @hibernate.set table="`DataFileItemSubTypes`" lazy="true"
     144    @hibernate.set lazy="true" inverse="true"
    146145    @hibernate.collection-key column="`datafiletype_id`"
    147     @hibernate.collection-many-to-many column="`itemsubtype_id`" class="net.sf.basedb.core.data.ItemSubtypeData"
    148   */
    149   public Set<ItemSubtypeData> getItemSubtypes()
    150   {
    151     if (itemSubtypes == null) itemSubtypes = new HashSet<ItemSubtypeData>();
     146    @hibernate.collection-one-to-many class="net.sf.basedb.core.data.ItemSubtypeFileTypeData"
     147  */
     148  Set<ItemSubtypeFileTypeData> getItemSubtypes()
     149  {
    152150    return itemSubtypes;
    153151  }
    154   void setItemSubtypes(Set<ItemSubtypeData> itemSubtypes)
     152  void setItemSubtypes(Set<ItemSubtypeFileTypeData> itemSubtypes)
    155153  {
    156154    this.itemSubtypes = itemSubtypes;
  • trunk/src/core/net/sf/basedb/core/data/FileSetData.java

    r4517 r5713  
    2222package net.sf.basedb.core.data;
    2323
    24 import java.util.HashMap;
    25 import java.util.Map;
     24import java.util.HashSet;
     25import java.util.Set;
    2626
    2727/**
     
    5555  }
    5656 
    57   private Map<DataFileTypeData, FileSetMemberData> members;
     57  private Set<FileSetMemberData> members;
    5858  /**
    5959    The members of this file set. This is the inverse end.
    6060    @see FileSetMemberData#getFileSet()
    61     @hibernate.map lazy="true" cascade="delete" inverse="true"
     61    @hibernate.set lazy="true" cascade="delete" inverse="true"
    6262    @hibernate.collection-key column="`fileset_id`"
    63     @hibernate.index-many-to-many column="`datafiletype_id`" class="net.sf.basedb.core.data.DataFileTypeData"
    6463    @hibernate.collection-one-to-many class="net.sf.basedb.core.data.FileSetMemberData"
     64    @since 3.0 (was returning a Map in BASE 2.x)
    6565  */
    66   public Map<DataFileTypeData, FileSetMemberData> getMembers()
     66  public Set<FileSetMemberData> getMembers()
    6767  {
    6868    if (members == null)
    6969    {
    70       members = new HashMap<DataFileTypeData, FileSetMemberData>();
     70      members = new HashSet<FileSetMemberData>();
    7171    }
    7272    return members;
    7373  }
    74   void setMembers(Map<DataFileTypeData, FileSetMemberData> members)
     74  void setMembers(Set<FileSetMemberData> members)
    7575  {
    7676    this.members = members;
  • trunk/src/core/net/sf/basedb/core/data/FileSetMemberData.java

    r5063 r5713  
    4343    Get the file set this file belongs to.
    4444    @hibernate.many-to-one outer-join="false" update="false"
    45     @hibernate.column name="`fileset_id`" not-null="true" unique-key="uniquetype"
     45    @hibernate.column name="`fileset_id`" not-null="true"
    4646  */
    4747  public FileSetData getFileSet()
     
    5858    Get the type of this file. A set may only contain one file for each type.
    5959    @hibernate.many-to-one outer-join="false" update="false"
    60     @hibernate.column name="`datafiletype_id`" not-null="true" unique-key="uniquetype"
     60    @hibernate.column name="`datafiletype_id`" not-null="true"
    6161  */
    6262  public DataFileTypeData getDataFileType()
  • trunk/src/core/net/sf/basedb/core/data/ItemSubtypeData.java

    r5698 r5713  
    2424import java.util.Date;
    2525import java.util.HashMap;
    26 import java.util.HashSet;
    2726import java.util.Map;
    2827import java.util.Set;
     
    172171  }
    173172 
    174   private Set<DataFileTypeData> dataFileTypes;
     173  private Map<DataFileTypeData, ItemSubtypeFileTypeData> fileTypes;
    175174  /**
    176     This is the inverse end. See {@link DataFileTypeData#getItemSubtypes()}.
    177 
    178     @hibernate.set table="`DataFileItemSubTypes`" lazy="true"
    179     @hibernate.collection-key column="`itemsubtype_id`"
    180     @hibernate.collection-many-to-many column="`datafiletype_id`" class="net.sf.basedb.core.data.DataFileTypeData"
     175    The file types that can be used on items of this subtype.
     176    This is the inverse end.
     177    @see ItemSubtypeFileTypeData#getItemSubtype()
     178    @hibernate.map lazy="true" cascade="delete" inverse="true"
     179    @hibernate.collection-key column="`subtype_id`"
     180    @hibernate.index-many-to-many column="`datafiletype_id`" class="net.sf.basedb.core.data.DataFileTypeData"
     181    @hibernate.collection-one-to-many class="net.sf.basedb.core.data.ItemSubtypeFileTypeData"
    181182  */
    182   public Set<DataFileTypeData> getDataFileTypes()
     183  public Map<DataFileTypeData, ItemSubtypeFileTypeData> getFileTypes()
    183184  {
    184     if (dataFileTypes == null) dataFileTypes = new HashSet<DataFileTypeData>();
    185     return dataFileTypes;
     185    if (fileTypes == null)
     186    {
     187      fileTypes = new HashMap<DataFileTypeData, ItemSubtypeFileTypeData>();
     188    }
     189    return fileTypes;
    186190  }
    187   void setDataFileTypes(Set<DataFileTypeData> dataFileTypes)
     191  void setFileTypes(Map<DataFileTypeData, ItemSubtypeFileTypeData> fileTypes)
    188192  {
    189     this.dataFileTypes = dataFileTypes;
     193    this.fileTypes = fileTypes;
    190194  }
    191195
  • trunk/src/core/net/sf/basedb/core/data/PlatformFileTypeData.java

    r4517 r5713  
    9696  }
    9797
     98  private boolean multiple;
     99  /**
     100    If multiple files of this type are allowed in a file set or not.
     101    @hibernate.property column="`allow_multiple`" type="boolean" not-null="true"
     102  */
     103  public boolean getAllowMultiple()
     104  {
     105    return multiple;
     106  }
     107  public void setAllowMultiple(boolean multiple)
     108  {
     109    this.multiple = multiple;
     110  }
     111
     112 
    98113}
  • trunk/src/core/net/sf/basedb/util/affymetrix/AffymetrixUtil.java

    r5623 r5713  
    2121*/
    2222package net.sf.basedb.util.affymetrix;
     23
     24import java.util.List;
    2325
    2426import affymetrix.fusion.cdf.FusionCDFData;
     
    6365  /**
    6466    Check if the CEL file on the raw bioassay matches the CDF file on the
    65     array design.
     67    array design. If the array design has more than one CDF file only the
     68    first one is used. If the raw bioassay has more than one CEL file, each
     69    file will be validated against the CDF.
    6670   
    6771    @param rawBioAssay The raw bioassay
     
    7680  {
    7781    DbControl dc = rawBioAssay.getDbControl();
    78     File celFile = FileStoreUtil.getDataFile(dc, rawBioAssay, DataFileType.AFFYMETRIX_CEL, false);
     82    List<File> celFiles = FileStoreUtil.getDataFiles(dc, rawBioAssay, DataFileType.AFFYMETRIX_CEL, false);
    7983    File cdfFile = FileStoreUtil.getDataFile(dc, design, DataFileType.AFFYMETRIX_CDF, false);
    80     if (celFile != null && cdfFile != null)
     84    if (cdfFile != null && celFiles != null && celFiles.size() > 0)
    8185    {
    8286      String cdfChipType = cdfFile.getName();
    8387      CelValidator celValidator = new CelValidator();
    8488      CdfValidator cdfValidator = new CdfValidator();
    85       FusionCELData cel = celValidator.loadCelFile(celFile);
    8689      FusionCDFData cdf = cdfValidator.loadCdfFile(cdfFile);
    87       celValidator.validateCelAndCdf(cel, cdf, cdfChipType);
     90     
     91      for (File celFile : celFiles)
     92      {
     93        FusionCELData cel = celValidator.loadCelFile(celFile);
     94        celValidator.validateCelAndCdf(cel, cdf, cdfChipType);
     95      }
    8896    }
    8997    else if (required)
    9098    {
    91       if (celFile == null)
     99      if (celFiles == null || celFiles.size() == 0)
    92100      {
    93101        throw new InvalidDataException("Raw bioassay has no CEL file: " + rawBioAssay);
  • trunk/src/core/net/sf/basedb/util/overview/validator/DataFileValidator.java

    r5651 r5713  
    161161            pvName = platform.getName();
    162162          }
     163          // TODO #1604
     164          /*
    163165          if (platform.getFileType(fileType, variant) == null)
    164166          {
     
    170172              );
    171173          }
     174          */
    172175        }
    173176      }
  • trunk/src/plugins/core/net/sf/basedb/plugins/CdfFileReporterImporter.java

    r5630 r5713  
    385385          int currentArrayDesignId = sc.getCurrentContext(Item.ARRAYDESIGN).getId();
    386386          design = ArrayDesign.getById(dc, currentArrayDesignId);
    387           cdfFile = FileStoreUtil.getDataFile(dc, design, DataFileType.AFFYMETRIX_CDF, false);
    388           presets = Arrays.asList(new File[] { cdfFile } );
     387          presets = FileStoreUtil.getDataFiles(dc, design, DataFileType.AFFYMETRIX_CDF, false);
    389388        }
    390389       
     
    395394          "CDF file",
    396395          "The CDF file to import probesets IDs from",
    397           presets != null ?
     396          presets != null && presets.size() > 0 ?
    398397            new ItemParameterType<File>(File.class, cdfFile, true, 1, presets) :
    399398            new FileParameterType(cdfFile, true, 1)
  • trunk/src/plugins/core/net/sf/basedb/plugins/batchimport/ArrayDesignImporter.java

    r5642 r5713  
    319319        else
    320320        {
    321           design.getFileSet().removeMember(fileType);
     321          // TODO #1604
     322          //design.getFileSet().removeMember(fileType);
    322323        }
    323324      }
  • trunk/src/plugins/core/net/sf/basedb/plugins/batchimport/DerivedBioAssayImporter.java

    r5696 r5713  
    397397        else
    398398        {
    399           bioAssay.getFileSet().removeMember(fileType);
     399          // TODO #1604
     400          //bioAssay.getFileSet().removeMember(fileType);
    400401        }
    401402      }
  • trunk/src/plugins/core/net/sf/basedb/plugins/batchimport/RawBioAssayImporter.java

    r5696 r5713  
    467467        else
    468468        {
    469           rba.getFileSet().removeMember(fileType);
     469          // TODO #1604
     470          //rba.getFileSet().removeMember(fileType);
    470471        }
    471472      }
  • trunk/src/plugins/core/net/sf/basedb/plugins/batchimport/ScanImporter.java

    r5697 r5713  
    261261      else
    262262      {
    263         scan.getFileSet().removeMember(imageType);
     263        // TODO #1604
     264        //scan.getFileSet().removeMember(imageType);
    264265      }
    265266    }
  • trunk/src/test/TestBasicAnalysis.java

    r5630 r5713  
    960960        {
    961961          files.add(fm.getFile());
    962           fs.removeMember(fm.getDataFileType());
     962          fs.removeMember(fm);
    963963        }
    964964      }
  • trunk/src/test/TestPlatform.java

    r5630 r5713  
    7272    int celId = TestDataFileType.get_id_for_external("affymetrix.cel");
    7373    int cdfId = TestDataFileType.get_id_for_external("affymetrix.cdf");
    74     test_add_filetype(id2, 0, celId, true);
    75     test_add_filetype(id2, idVariant2, cdfId, false);
    76     test_add_filetype(id2, idVariant2b, fileTypeId, false);
     74    test_add_filetype(id2, 0, celId, true, false);
     75    test_add_filetype(id2, idVariant2, cdfId, false, false);
     76    test_add_filetype(id2, idVariant2b, fileTypeId, false, true);
    7777    test_list_filetypes(id2, 0, false, 3);
    7878    test_list_filetypes(id2, 0, true, 1);
     
    255255    {
    256256      write("   \tID \tName      \tDescription\tExternal ID\tFile only\tRaw data type");
    257       write("-- \t-- \t--------- \t-----------\t---------\t---------\t-------------");
     257      write("-- \t-- \t--------- \t-----------\t-----------\t---------\t-------------");
    258258    }
    259259  }
     
    287287    {
    288288      System.out.println(i+":\t"+ft.getId()+"\t"+ft.getPlatform()+"\t"+
    289           ft.getVariant() + "\t" + ft.getDataFileType());
     289          ft.getVariant() + "\t" + ft.getDataFileType() + "\t" + ft.isRequired() + "\t" + ft.getAllowMultiple());
    290290    }
    291291  }
     
    397397  }
    398398
    399   static void test_add_filetype(int platformId, int variantId, int fileTypeId, boolean required)
     399  static void test_add_filetype(int platformId, int variantId, int fileTypeId, boolean required, boolean multiple)
    400400  {
    401401    if (platformId == 0 || fileTypeId == 0) return;
     
    409409      DataFileType fileType = DataFileType.getById(dc, fileTypeId);
    410410     
    411       p.addFileType(fileType, required, v);
     411      PlatformFileType pf = p.getFileType(fileType, v, true);
     412      pf.setRequired(required);
     413      pf.setAllowMultiple(multiple);
    412414     
    413415      dc.commit();
  • trunk/www/admin/datafiletypes/view_filetype.jsp

    r5623 r5713  
    272272          title="Required"
    273273        />
     274        <tbl:columndef
     275          id="multiple"
     276          title="Multiple files"
     277        />
    274278        <tbl:data>
    275279          <tbl:columns>
     
    294298                /><%=v == null ? "<i>- all -</i>" : Base.getLinkedName(ID, v, false, true)%></tbl:cell>
    295299              <tbl:cell column="required"><%=item.isRequired() ? "yes" : "no"%></tbl:cell>
     300              <tbl:cell column="multiple"><%=item.getAllowMultiple() ? "yes" : "no"%></tbl:cell>
    296301            </tbl:row>
    297302            <%
  • trunk/www/admin/itemsubtypes/edit_subtype.jsp

    r5706 r5713  
    3030  import="net.sf.basedb.core.Permission"
    3131  import="net.sf.basedb.core.ItemSubtype"
     32  import="net.sf.basedb.core.ItemSubtypeFileType"
    3233  import="net.sf.basedb.core.PermissionDeniedException"
    3334  import="net.sf.basedb.core.Metadata"
     
    6364  String title = null;
    6465  ItemSubtype subtype = null;
    65   ItemQuery<DataFileType> fileTypesQuery = null;
     66  ItemQuery<ItemSubtypeFileType> fileTypesQuery = null;
    6667 
    6768  if (itemId == 0)
     
    109110      if (TabControl.validateActiveTab('settings'))
    110111      {
    111         frm.addedFileTypes.value = Link.getActionIds(1, 'F').join(',');
     112        frm.modifiedFileTypes.value = Link.exportModified(frm, 'F', true).join(',');
    112113        frm.removedFileTypes.value = Link.getActionIds(-1, 'F').join(',');
    113114        frm.submit();
     
    139140      {
    140141        fileTypesQuery.include(Include.ALL);
    141         fileTypesQuery.order(Orders.asc(Hql.property("name")));
    142         for (DataFileType fileType : fileTypesQuery.list(dc))
     142        fileTypesQuery.order(Orders.asc(Hql.property("itemSubtype.name")));
     143        for (ItemSubtypeFileType ft : fileTypesQuery.list(dc))
    143144        {
     145          DataFileType dft = ft.getDataFileType();
     146          boolean required = ft.isRequired();
     147          boolean multiple = ft.getAllowMultiple();
     148          int value = 0;
     149          if (required) value += 1;
     150          if (multiple) value += 2;
    144151          %>
    145           Link.addNewItem(fileTypes, new Item('F', <%=fileType.getId()%>, '<%=HTML.javaScriptEncode(fileType.getName())%>'));
     152          Link.addNewItem(fileTypes, new Item('F', <%=dft.getId()%>, '<%=HTML.javaScriptEncode(dft.getName())%> <%=required ? "[×]" : "[-]"%>', <%=value%>));
    146153          <%
    147154        }
     
    254261    {
    255262      var item = Link.getItem('F', fileTypeId);
    256       if (!item) item = new Item('F', fileTypeId, name);
    257       Link.addItem(document.forms['subtype'].fileTypes, item);
    258     }
     263      var frm = document.forms['subtype'];
     264      var required = frm.required.checked;
     265      var multiple = frm.multiple.checked;
     266      var newValue = 0;
     267      if (required) newValue += 1;
     268      if (multiple) newValue += 2;
     269      if (!item) item = new Item('F', fileTypeId, name+(required ? '[×]' : '[-]'), newValue, '');
     270      Link.addItem(frm.fileTypes, item);
     271    }
     272
    259273    function removeFileTypesOnClick()
    260274    {
    261275      Link.removeSelected(document.forms['subtype'].fileTypes);
     276    }
     277    function fileTypesOnChange()
     278    {
     279      var frm = document.forms['subtype'];
     280      var item = frm.fileTypes[frm.fileTypes.selectedIndex].item;
     281      if (item && item.id)
     282      {
     283        frm.required.checked = (item.value & 1) > 0;
     284        frm.multiple.checked = (item.value & 2) > 0;
     285      }
     286      else
     287      {
     288        frm.required.checked = false;
     289        frm.multiple.checked = false;
     290      }
     291    }
     292
     293    function requiredOnClick()
     294    {
     295      var frm = document.forms['subtype'];
     296      var required = frm.required.checked;
     297      var multiple = frm.multiple.checked;
     298      var newValue = 0;
     299      if (required) newValue += 1;
     300      if (multiple) newValue += 2;
     301      for (var i = 0; i < frm.fileTypes.length; i++)  // >
     302      {
     303        var option = frm.fileTypes[i];
     304        if (option.selected && option.item.id)
     305        {
     306          option.item.value = newValue;
     307          var text = option.text.replace(/\[.*\]/, '['+(required ? '×' : '-') +']');
     308          option.text = text;
     309        }
     310      }
     311    }
     312    function multipleOnClick()
     313    {
     314      requiredOnClick();
    262315    }
    263316
     
    358411          <tr valign="top">
    359412          <td>
    360             <select name="fileTypes" size="10" multiple style="width: 20em;">
     413            <select name="fileTypes" size="10" multiple style="width: 20em;"
     414              onchange="fileTypesOnChange()">
    361415            </select>
    362             <input type="hidden" name="addedFileTypes" value="">
     416            <input type="hidden" name="modifiedFileTypes" value="">
    363417            <input type="hidden" name="removedFileTypes" value="">
    364418          </td>
     
    376430            /></td></tr>
    377431            </table>
     432          <input type="checkbox" id="required" name="required" value="1" onchange="requiredOnClick()">
     433            <label for="required">Required</label><br>
     434          <input type="checkbox" id="multiple" name="multiple" value="1" onchange="multipleOnClick()">
     435            <label for="multiple">Allow multiple files</label>
    378436          </td>
    379437          </tr>
  • trunk/www/admin/itemsubtypes/index.jsp

    r5698 r5713  
    3030  import="net.sf.basedb.core.ItemSubtype"
    3131  import="net.sf.basedb.core.DataFileType"
     32  import="net.sf.basedb.core.ItemSubtypeFileType"
    3233  import="net.sf.basedb.core.ItemQuery"
    3334  import="net.sf.basedb.core.Permission"
     
    173174      }
    174175
    175       String[] removeFileTypes = Values.getString(request.getParameter("removedFileTypes")).split(",");
    176       for (int i = 0; i < removeFileTypes.length; ++i)
     176      // Data file types
     177      String[] modifiedFileTypes = Values.getString(request.getParameter("modifiedFileTypes")).split(",");
     178      for (int i = 0; i < modifiedFileTypes.length; ++i)
    177179      {
    178         int fileTypeId = Values.getInt(removeFileTypes[i], -1);
    179         if (fileTypeId != -1) subtype.removeAssociatedDataFileType(DataFileType.getById(dc, fileTypeId));
     180        int ftId = Values.getInt(modifiedFileTypes[i], -1);
     181        if (ftId != -1)
     182        {
     183          DataFileType dft = DataFileType.getById(dc, ftId);
     184          int options = Values.getInt(request.getParameter("F"+ftId));
     185          ItemSubtypeFileType sft = subtype.getAssociatedDataFileType(dft, true);
     186          sft.setRequired((options & 1) > 0);
     187          sft.setAllowMultiple((options & 2) > 0);
     188        }
    180189      }
    181      
    182       String[] addFileTypes = Values.getString(request.getParameter("addedFileTypes")).split(",");
    183       for (int i = 0; i < addFileTypes.length; ++i)
     190      String[] removedFileTypes = Values.getString(request.getParameter("removedFileTypes")).split(",");
     191      for (int i = 0; i < removedFileTypes.length; ++i)
    184192      {
    185         int fileTypeId = Values.getInt(addFileTypes[i], -1);
    186         if (fileTypeId != -1) subtype.addAssociatedDataFileType(DataFileType.getById(dc, fileTypeId));
     193        int ftId = Values.getInt(removedFileTypes[i], -1);
     194        if (ftId != -1)
     195        {
     196          DataFileType dft = DataFileType.getById(dc, ftId);
     197          subtype.removeAssociatedDataFileType(dft);
     198        }
    187199      }
    188200
  • trunk/www/admin/itemsubtypes/view_subtype.jsp

    r5698 r5713  
    3535  import="net.sf.basedb.core.ItemSubtype"
    3636  import="net.sf.basedb.core.DataFileType"
     37  import="net.sf.basedb.core.ItemSubtypeFileType"
    3738  import="net.sf.basedb.core.PermissionDeniedException"
    3839  import="net.sf.basedb.core.PluginDefinition"
     
    315316
    316317      <%
    317       ItemQuery<DataFileType> fileTypeQuery = subtype.getDataFileTypes();
     318      ItemQuery<ItemSubtypeFileType> fileTypeQuery = subtype.getDataFileTypes();
    318319      fileTypeQuery.include(Include.ALL);
    319       fileTypeQuery.order(Orders.asc(Hql.property("name")));
    320       ItemResultList<DataFileType> fileTypes = fileTypeQuery.list(dc);
     320      fileTypeQuery.order(Orders.asc(Hql.property("itemSubtype.name")));
     321      ItemResultList<ItemSubtypeFileType> fileTypes = fileTypeQuery.list(dc);
    321322      if (fileTypes.size() == 0)
    322323      {
     
    348349            />
    349350            <tbl:columndef
     351              id="required"
     352              title="Required"
     353            />
     354            <tbl:columndef
     355              id="multiple"
     356              title="Multiple files"
     357            />
     358            <tbl:columndef
     359              id="genericType"
     360              title="Generic type"
     361            />
     362            <tbl:columndef
    350363              id="description"
    351364              title="Description"
     
    356369              <tbl:rows>
    357370              <%
    358               for (DataFileType fileType : fileTypes)
     371              for (ItemSubtypeFileType fileType : fileTypes)
    359372              {
     373                DataFileType dft = fileType.getDataFileType();
    360374                %>
    361375                <tbl:row>
     
    363377                      image="deleted.gif"
    364378                      tooltip="This item has been scheduled for deletion"
    365                       visible="<%=fileType.isRemoved()%>"
    366                     /><%=Base.getLinkedName(ID, fileType, false, true)%></tbl:cell>
    367                   <tbl:cell column="extension"><%=HTML.encodeTags(fileType.getExtension()) %></tbl:cell>
    368                   <tbl:cell column="description"><%=HTML.encodeTags(fileType.getDescription())%></tbl:cell>
     379                      visible="<%=dft.isRemoved()%>"
     380                    /><%=Base.getLinkedName(ID, dft, false, true)%></tbl:cell>
     381                  <tbl:cell column="extension"><%=HTML.encodeTags(dft.getExtension()) %></tbl:cell>
     382                  <tbl:cell column="required"><%=fileType.isRequired() ? "yes" : "no"%></tbl:cell>
     383                  <tbl:cell column="multiple"><%=fileType.getAllowMultiple() ? "yes" : "no"%></tbl:cell>
     384                  <tbl:cell column="genericType"><base:propertyvalue item="<%=dft%>" property="genericType" /></tbl:cell>
     385                  <tbl:cell column="description"><%=HTML.encodeTags(dft.getDescription())%></tbl:cell>
    369386                </tbl:row>
    370387                <%
  • trunk/www/admin/platforms/edit_platform.jsp

    r5574 r5713  
    182182          DataFileType dft = ft.getDataFileType();
    183183          boolean required = ft.isRequired();
     184          boolean multiple = ft.getAllowMultiple();
     185          int value = 0;
     186          if (required) value += 1;
     187          if (multiple) value += 2;
    184188          %>
    185           Link.addNewItem(fileTypes, new Item('F', <%=dft.getId()%>, '<%=HTML.javaScriptEncode(dft.getName())%> <%=required ? "[×]" : "[-]"%>', '<%=required ? "1" : "0"%>'));
     189          Link.addNewItem(fileTypes, new Item('F', <%=dft.getId()%>, '<%=HTML.javaScriptEncode(dft.getName())%> <%=required ? "[×]" : "[-]"%>', <%=value%>));
    186190          <%
    187191        }
     
    199203      var frm = document.forms['platform'];
    200204      var required = frm.required.checked;
    201       if (!item) item = new Item('F', fileTypeId, name+(required ? '[×]' : '[-]'), required ? '1' : '0', '');
     205      var multiple = frm.multiple.checked;
     206      var newValue = 0;
     207      if (required) newValue += 1;
     208      if (multiple) newValue += 2;
     209      if (!item) item = new Item('F', fileTypeId, name+(required ? '[×]' : '[-]'), newValue, '');
    202210      Link.addItem(frm.fileTypes, item);
    203211    }
     
    212220      if (item && item.id)
    213221      {
    214         frm.required.checked = item.value != '0';
     222        frm.required.checked = (item.value & 1) > 0;
     223        frm.multiple.checked = (item.value & 2) > 0;
    215224      }
    216225      else
    217226      {
    218227        frm.required.checked = false;
     228        frm.multiple.checked = false;
    219229      }
    220230    }
     
    223233      var frm = document.forms['platform'];
    224234      var required = frm.required.checked;
     235      var multiple = frm.multiple.checked;
     236      var newValue = 0;
     237      if (required) newValue += 1;
     238      if (multiple) newValue += 2;
    225239      for (var i = 0; i < frm.fileTypes.length; i++)  // >
    226240      {
     
    228242        if (option.selected && option.item.id)
    229243        {
    230           option.item.value = required ? '1' : '0';
     244          option.item.value = newValue;
    231245          var text = option.text.replace(/\[.*\]/, '['+(required ? '×' : '-') +']');
    232246          option.text = text;
    233247        }
    234248      }
     249    }
     250    function multipleOnClick()
     251    {
     252      requiredOnClick();
    235253    }
    236254    </script>
     
    340358          onchange="fileTypesOnChange()">
    341359        </select>&nbsp;<br>
    342         × = Required
    343         <input type="checkbox" name="required" value="1" onchange="requiredOnClick()">
    344360        <input type="hidden" name="modifiedFileTypes" value="">
    345361        <input type="hidden" name="removedFileTypes" value="">
     
    359375        /></td></tr>
    360376        </table>
     377        <input type="checkbox" id="required" name="required" value="1" onchange="requiredOnClick()">
     378          <label for="required">Required</label><br>
     379        <input type="checkbox" id="multiple" name="multiple" value="1" onchange="multipleOnClick()">
     380          <label for="multiple">Allow multiple files</label>
    361381      </td>
    362382      </tr>     
  • trunk/www/admin/platforms/index.jsp

    r5590 r5713  
    192192        {
    193193          DataFileType dft = DataFileType.getById(dc, ftId);
    194           boolean required = Values.getBoolean(request.getParameter("F"+ftId));
    195           platform.addFileType(dft, required, null);
     194          int options = Values.getInt(request.getParameter("F"+ftId));
     195          PlatformFileType pft = platform.getFileType(dft, null, true);
     196          pft.setRequired((options & 1) > 0);
     197          pft.setAllowMultiple((options & 2) > 0);
    196198        }
    197199      }
  • trunk/www/admin/platforms/view_platform.jsp

    r5509 r5713  
    316316          />
    317317          <tbl:columndef
     318            id="multiple"
     319            title="Multiple files"
     320          />
     321          <tbl:columndef
    318322            id="genericType"
    319323            title="Generic type"
     
    345349                  /><%=Base.getLinkedName(ID, dft, false, true)%></tbl:cell>
    346350                <tbl:cell column="required"><%=fileType.isRequired() ? "yes" : "no"%></tbl:cell>
     351                <tbl:cell column="multiple"><%=fileType.getAllowMultiple() ? "yes" : "no"%></tbl:cell>
    347352                <tbl:cell column="genericType"><base:propertyvalue item="<%=dft%>" property="genericType" /></tbl:cell>
    348353                <tbl:cell column="description"><%=HTML.niceFormat(dft.getDescription())%></tbl:cell>
  • trunk/www/common/datafiles/list_files.jsp

    r5698 r5713  
    2323  @version 2.0
    2424--%>
    25 <%@page import="net.sf.basedb.core.Subtypable"%>
    26 <%@page import="net.sf.basedb.core.ItemSubtype"%>
    2725<%@ page pageEncoding="UTF-8" session="false"
    2826  import="net.sf.basedb.core.SessionControl"
     
    3533  import="net.sf.basedb.core.PlatformFileType"
    3634  import="net.sf.basedb.core.DataFileType"
     35  import="net.sf.basedb.core.Subtypable"
     36  import="net.sf.basedb.core.ItemSubtype"
    3737  import="net.sf.basedb.core.FileSet"
    3838  import="net.sf.basedb.core.FileSetMember"
    3939  import="net.sf.basedb.core.File"
    4040  import="net.sf.basedb.core.FileStoreEnabled"
     41  import="net.sf.basedb.core.UsableDataFileType"
     42  import="net.sf.basedb.core.ItemSubtypeFileType"
    4143  import="net.sf.basedb.core.Nameable"
    4244  import="net.sf.basedb.core.ItemQuery"
     
    127129  {
    128130    ItemQuery<FileSetMember> query = fileSet.getMembers();
     131    query.order(Orders.asc(Hql.property("dataFileType.name")));
     132    query.order(Orders.asc(Hql.property("file.name")));
    129133    for (FileSetMember member : query.list(dc))
    130134    {
     
    168172
    169173  // Load platform file types
    170   Map<DataFileType, PlatformFileType> platformFileTypes =
    171     new HashMap<DataFileType, PlatformFileType>();
     174  Map<DataFileType, UsableDataFileType> usableFileTypes =
     175    new HashMap<DataFileType, UsableDataFileType>();
    172176  if (platform != null)
    173177  {
     
    179183      {
    180184        dft = pft.getDataFileType();
    181         platformFileTypes.put(dft, pft);
     185        usableFileTypes.put(dft, pft);
    182186        if (dft.getItemType() == itemType && !existing.contains(dft))
    183187        {
     
    193197  if (subtype != null)
    194198  {
    195     ItemQuery<DataFileType> query = subtype.getDataFileTypes();
    196     for (DataFileType dft : query.list(dc))
    197     {
    198       if (!existing.contains(dft))
    199       {
    200         members.add(new DataFile(dft, null, null));
    201       }
     199    ItemQuery<ItemSubtypeFileType> query = subtype.getDataFileTypes();
     200    for (ItemSubtypeFileType sft : query.list(dc))
     201    {
     202      DataFileType dft = null;
     203      try
     204      {
     205        dft = sft.getDataFileType();
     206        usableFileTypes.put(dft, sft);
     207        if (dft.getItemType() == itemType && !existing.contains(dft))
     208        {
     209          members.add(new DataFile(dft, null, null));
     210        }
     211      }
     212      catch (Throwable t)
     213      {}
    202214    }
    203215  }
     
    278290              }
    279291            }
    280             PlatformFileType pft = platformFileTypes.get(dft);
    281             boolean isRequired = pft == null ? false : pft.isRequired();
    282             boolean isPartOfPlatform = pft != null || (subtype != null && subtype.isAssociatedDataFileType(dft));
     292            UsableDataFileType uft = usableFileTypes.get(dft);
     293            boolean isRequired = uft == null ? false : uft.isRequired();
     294            boolean isPartOfPlatform = uft != null || (subtype != null && subtype.isAssociatedDataFileType(dft));
    283295            String icon = null;
    284296            if (member == null)
  • trunk/www/common/datafiles/select_files.jsp

    r5698 r5713  
    3939  import="net.sf.basedb.core.PlatformVariant"
    4040  import="net.sf.basedb.core.PlatformFileType"
     41  import="net.sf.basedb.core.UsableDataFileType"
    4142  import="net.sf.basedb.core.DataFileType"
    4243  import="net.sf.basedb.core.Subtypable"
     
    5960  import="java.util.List"
    6061  import="java.util.Date"
    61   import="java.util.Set"
    62   import="java.util.HashSet"
    63   import="java.util.TreeSet"
     62  import="java.util.Map"
     63  import="java.util.HashMap"
    6464%>
    6565<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
     
    8282  final FileStoreEnabled item = itemId == 0 ? null : (FileStoreEnabled)itemType.getById(dc, itemId);
    8383  FileSet fileSet = null;
     84  // Get the current files organized per data file type
     85  Map<DataFileType, List<FileSetMember>> members = new HashMap<DataFileType, List<FileSetMember>>();
    8486  if (item != null && item.hasFileSet())
    8587  {
    8688    fileSet = item.getFileSet();
     89    ItemQuery<FileSetMember> query = fileSet.getMembers();
     90    query.order(Orders.asc(Hql.property("dataFileType.name")));
     91    query.order(Orders.asc(Hql.property("file.name")));
     92    List<FileSetMember> all = query.list(dc);
     93    for (FileSetMember m : all)
     94    {
     95      DataFileType dft = m.getDataFileType();
     96      List<FileSetMember> tmp = members.get(dft);
     97      if (tmp == null)
     98      {
     99        tmp = new ArrayList<FileSetMember>();
     100        members.put(dft, tmp);
     101      }
     102      tmp.add(m);
     103    }
    87104  }
    88105
     
    127144    Base.getDataFileTypes(itemType, item, platform, variant, itemSubtype);
    128145  List<DataFileType> fileTypes = fileTypeQuery.list(dc);
    129  
    130  
    131146  String title = "Select data files for " +
    132147    HTML.encodeTags((item instanceof Nameable ? ((Nameable)item).getName() :
     
    135150  final String clazz = "class=\"text\"";
    136151  final String requiredClazz = "class=\"text required\"";
    137   final StringBuilder sb = new StringBuilder();
    138   List<File> recentFiles = null;
    139  
    140152  %>
    141 <base:page type="popup" title="<%=title%>">
    142   <base:head scripts="" styles="parameters.css">
     153  <base:page type="popup" title="<%=title%>">
     154  <base:head >
    143155 
    144156  <script language="JavaScript">
    145157  function init()
    146158  {
    147   }
    148   var lastFileInputName;
     159    if (document.body.addEventListener)
     160    {
     161      // Mozilla
     162      document.body.addEventListener('click', hideVisibleRecentFilesDiv, false);
     163    }
     164    else
     165    {
     166      // IE.
     167      div.onclick = hideVisibleRecentFilesDiv;
     168    }
     169
     170  }
     171 
     172  var lastFileTypeId;
    149173  var updateCheckboxes = false;
    150   function browseOnClick(inputName, extension, updateCheck)
     174  function addFilesOnClick(fileTypeId, extension, updateCheck)
     175  {
     176    var frm = document.forms['datafiles'];
     177    updateCheckboxes = updateCheck;
     178    var url = '../../filemanager/index.jsp?ID=<%=ID%>&cmd=SelectMultiple&callback=addFileCallback';
     179    if (extension)
     180    {
     181      url += '&resetTemporary=1&tmpfilter:STRING:name='+escape('%.' + extension);
     182    }
     183    else
     184    {
     185      url += '&resetTemporary=1&filter:STRING:name=';
     186    }
     187    lastFileTypeId = fileTypeId;
     188    Main.openPopup(url, 'SelectFile', 1000, 700);
     189  }
     190  function addFileCallback(fileId, path)
     191  {
     192    addFile(lastFileTypeId, fileId, path);
     193  }
     194  function removeFilesOnClick(inputName, updateCheck)
     195  {
     196  }
     197 
     198  function browseOnClick(fileTypeId, extension, updateCheck)
    151199  {
    152200    var frm = document.forms['datafiles'];
     
    161209      url += '&resetTemporary=1&filter:STRING:name=';
    162210    }
    163     lastFileInputName = inputName;
     211    lastFileTypeId = fileTypeId;
    164212    Main.openPopup(url, 'SelectFile', 1000, 700);
    165213  }
    166214  function setFileCallback(fileId, path)
    167215  {
     216    setFile(lastFileTypeId, fileId, path);
     217  }
     218  function setFile(fileTypeId, fileId, path)
     219  {
    168220    var frm = document.forms['datafiles'];
    169     frm[lastFileInputName].value = path;
    170     fileOnChange(lastFileInputName, updateCheckboxes);
    171   }
     221    document.getElementById('filelist.'+fileTypeId+'.file').innerHTML = path;
     222    new FileAction('setfile', fileTypeId, fileId);
     223  }
     224  function addFile(fileTypeId, fileId, path)
     225  {
     226    var fileDiv = document.getElementById('filelist.'+fileTypeId+'.'+fileId);
     227    if (fileDiv) return;
     228   
     229    fileDiv = document.createElement('div');
     230    fileDiv.id = 'filelist.'+fileTypeId+'.'+fileId;
     231    fileDiv.innerHTML = path;
     232    document.getElementById('filelist.'+fileTypeId+'.file').appendChild(fileDiv);
     233    Main.hide('filelist.'+fileTypeId+'.0');
     234    new FileAction('addfile', fileTypeId, fileId);
     235  }
     236  function removeOnClick(fileTypeId, updateCheck)
     237  {
     238    document.getElementById('filelist.'+fileTypeId+'.file').innerHTML = '<i>- not selected -</i>';
     239    new FileAction('setfile', fileTypeId, 0);
     240  }
     241 
     242  /*
    172243  function fileOnChange(inputName, updateCheckbox)
    173244  {
     
    179250    if (updateCheckbox)
    180251    {
    181       if (frm[inputName].value != '')
     252      if (frm[inputName].value != '' || frm[inputName].length > 0)
    182253      {
    183254        // Data filetype supports validation
    184255        if (validateCheckbox)
    185         {       
     256        {
    186257          if (validateCheckbox.disabled) validateCheckbox.disabled = false; 
    187258          validateCheckbox.checked = "1";
     
    190261    }   
    191262  }
    192   function recentOnChange(inputName, updateCheck)
    193   {
    194     var frm = document.forms['datafiles'];
    195     var recentInput = frm['recent.'+inputName];
    196     if (recentInput.selectedIndex > 0)
    197     {
    198       var option = recentInput[recentInput.selectedIndex];
    199       var path = option.value == '' ? '' : option.text;
    200       if (frm[inputName].value != path)
     263  */
     264 
     265  function writeFileActions()
     266  {
     267    Main.debug(fileActions.length, true);
     268    for (var i = 0; i < fileActions.length; i++)
     269    {
     270      var action = fileActions[i];
     271      Main.debug(action.action + ':' + action.fileTypeId + '='+action.fileId);
     272    }
     273  }
     274 
     275  var fileActions = new Array();
     276  function FileAction(action, fileTypeId, fileId)
     277  {
     278    this.action = action;
     279    this.fileTypeId = fileTypeId;
     280    this.fileId = fileId;
     281   
     282    if (action == 'setfile')
     283    {
     284      for (var i = 0; i < fileActions.length; i++)
    201285      {
    202         frm[inputName].value = path;
    203         fileOnChange(inputName, updateCheck);
     286        var other = fileActions[i];
     287        if (other.action == this.action && other.fileTypeId == this.fileTypeId)
     288        {
     289          fileActions[i] = this;
     290          return;
     291        }
    204292      }
    205       recentInput.selectedIndex = 0;
     293      fileActions[fileActions.length] = this;
     294    }
     295    else if (action == 'addfile')
     296    {
     297      for (var i = 0; i < fileActions.length; i++)
     298      {
     299        var other = fileActions[i];
     300        if (other.action == this.action && other.fileTypeId == this.fileTypeId && other.fileId == this.fileId)
     301        {
     302          return;
     303        }
     304      }
     305      fileActions[fileActions.length] = this;
     306    }
     307  }
     308 
     309  function writeFileActionsToForm(frm)
     310  {
     311    alert(fileActions.length);
     312    for (var i = 0; i < fileActions.length; i++)
     313    {
     314      var action = fileActions[i];
     315      Forms.createHidden(frm, action.action + '.' + action.fileTypeId, action.fileId);
     316    }
     317  }
     318 
     319  var visibleRecentFilesDiv = null;
     320  function recentFilesOnClick(event, fileTypeId)
     321  {
     322    var recentDiv = document.getElementById('recentfiles.'+fileTypeId);
     323    var currentDiv = visibleRecentFilesDiv;
     324    hideVisibleRecentFilesDiv();
     325    if (currentDiv == recentDiv) return;
     326   
     327    var fileCell = document.getElementById('filelist.'+fileTypeId+'.file');
     328    var pos = Main.getElementPosition(fileCell, true);
     329    Main.show('recentfiles.'+fileTypeId);
     330   
     331    recentDiv.style.top = (pos.bottom-2) + 'px';
     332    recentDiv.style.left = (pos.left) + 'px';
     333    recentDiv.style.width = (pos.width+18) + 'px';
     334
     335    visibleRecentFilesDiv = recentDiv;
     336    event.cancelBubble = true;
     337    event.stopPropagation();
     338  }
     339
     340  function selectRecentFile(fileTypeId, fileId)
     341  {
     342    var path = document.getElementById('recentfile.'+fileTypeId+'.'+fileId).innerHTML;
     343    setFile(fileTypeId, fileId, path);
     344  }
     345 
     346  function hideVisibleRecentFilesDiv()
     347  {
     348    if (visibleRecentFilesDiv)
     349    {
     350      visibleRecentFilesDiv.style.display = 'none';
     351      visibleRecentFilesDiv = null;
    206352    }
    207353  }
    208354  </script>
     355  <style>
     356  .filelist {
     357    overflow: auto;
     358    padding: 0px;
     359    border: 1px solid #cccccc;
     360    background: #FFFFFF;
     361  }
     362  .filelist td {
     363    border-bottom: 1px dotted #cccccc;
     364    padding: 1px 2px 1px 2px;
     365  }
     366  .filelist .filetype {
     367    width: 150px;
     368    font-weight: bold;
     369    background-color: #f0f0f0;
     370    border-right: 1px solid #cccccc;
     371    white-space: nowrap;
     372  }
     373  .filelist .file {
     374   
     375  }
     376  .filelist .required {
     377    background: #D0F0FF !important;
     378  }
     379  .filelist .fileaction {
     380    max-width: 18px;
     381    width: 18px;
     382    text-align: center;
     383  }
     384  .recentfiles {
     385    position: absolute;
     386    top: 0px;
     387    left: 0px;
     388    border: 1px solid #999999;
     389    background: #ffffff;
     390    text-align: left;
     391  }
     392  .recentfiles .recentfile {
     393    padding: 2px;
     394    border-bottom: 1px dotted #e0e0e0;
     395  }
     396  .recentfiles .recentfile:hover {
     397    cursor: pointer;
     398    background: #e0e0e0;
     399    padding: 2px;
     400  }
     401  </style>
    209402  </base:head>
    210403 
    211404  <base:body onload="init()" style="background: #E0E0E0;">
    212405
    213     <form name="datafiles">
     406    <div id="filelist" class="filelist" style="height: <%=(int)(scale*320)%>px; width:100%">
    214407    <%
     408    boolean hasNonPlatformFiles = true;     
     409    boolean activateCheckBoxes = false;
     410    boolean validationSupport = true;
    215411    if (fileTypes.size() == 0)
    216412    {
     
    240436    {
    241437      %>
    242       <table class="form" cellspacing="2" border="0" cellpadding="0" width="100%">
     438      <table border="0" cellspacing="0" cellpadding="0" width="100%">
    243439      <%
    244       boolean hasNonPlatformFiles = false;     
    245       boolean activateCheckBoxes = false;
    246 
    247       boolean validationSupport = false;
    248      
    249440      for (DataFileType dft : fileTypes)
    250441      {
    251         PlatformFileType pft = platform == null ?
    252           null : platform.getFileType(dft, variant);
    253         // If file type is not registered with a variant, also check if it is inherited from platform
    254         if (pft == null && variant != null) pft = platform.getFileType(dft, null);
    255         boolean isPartOfPlatform = pft != null || (itemSubtype != null && itemSubtype.isAssociatedDataFileType(dft));
    256         boolean isRequired = pft == null ? false : pft.isRequired();
    257         FileSetMember member = fileSet == null || !fileSet.hasMember(dft) ?
    258           null : fileSet.getMember(dft);
    259         File file = null;
    260         boolean deniedFile = false;
     442        String dftId = Integer.toString(dft.getId());
     443        String fullLabel = dft.getName();
     444        String label = Values.trimString(fullLabel, 25);
     445       
     446        UsableDataFileType usable = null;
     447        if (platform != null)
     448        {
     449          usable = platform.getFileType(dft, variant, false);
     450          if (usable == null && variant != null)
     451          {
     452            // If file type is not registered with a variant, also check if it is inherited from platform
     453            usable = platform.getFileType(dft, null, false);
     454          }
     455        }
     456        else if (itemSubtype != null)
     457        {
     458          usable = itemSubtype.getAssociatedDataFileType(dft, false);
     459        }
     460       
     461        boolean isPartOfPlatform = usable != null;
     462        boolean isRequired = usable == null ? false : usable.isRequired();
     463        boolean allowMultiple = usable == null ? false : usable.getAllowMultiple();
    261464        String extension = dft.getExtension();
    262        
    263465        boolean hasValidator = dft.hasActiveValidator(dc);
    264466        boolean affectCheckboxes = hasValidator;
    265467        validationSupport |= hasValidator;
    266         if (member != null)
    267         {
    268           try
    269           {
    270             file = member.getFile();           
    271           }
    272           catch (PermissionDeniedException ex)
    273           {
    274             deniedFile = true;
    275           }
    276         }
    277        
    278         String path = "";
    279         if (file != null)
    280         {
    281           path = file.getPath().toString();
    282           activateCheckBoxes |= hasValidator;
    283         }
    284         else if (deniedFile || deniedPlatform)
    285         {
    286           path = "- denied -";
    287         }
    288         String inputName= "datafile."+dft.getId();
    289         recentFiles = (List<File>)cc.getRecent(dc, Item.FILE, dft.getExternalId());
     468        List<FileSetMember> files = members.get(dft);
     469        List<File> recentFiles = (List<File>)cc.getRecent(dc, Item.FILE, dft.getExternalId());
    290470        %>
    291         <tr>
    292           <td class="prompt "><%=HTML.encodeTags(dft.getName())%>
    293           <%
    294           if (!isPartOfPlatform && !deniedPlatform)
    295           {
    296             hasNonPlatformFiles = true;
    297             %>
    298             <base:icon image="warning.gif" tooltip="This file is not part of the platform/subtype" />
     471        <tr class="item <%=isRequired ? "required" : "" %>"
     472          id="filelist.<%=dftId%>"
     473          onclick="itemOnClick(<%=dftId%>)">
     474          <td class="filetype"
     475            id="filelist.<%=dftId%>.label"
     476            title="<%=fullLabel == label ? "" : HTML.encodeTags(fullLabel)%>"
     477            ><%=HTML.encodeTags(label)%>
    299478            <%
    300           }
    301           %>
    302           </td>
    303           <td>
    304             <table border="0" cellspacing="0" cellpadding="0">
    305             <tr>
    306               <td>     
    307                 <input <%=isRequired ? requiredClazz : clazz%> type="text"
    308                 name="<%=inputName%>" value="<%=HTML.encodeTags(path)%>"
    309                 size="50" title="<%=HTML.encodeTags(dft.getDescription())%>"
    310                 <%=deniedFile || deniedPlatform ? "disabled" : "" %>
    311                 onchange="fileOnChange('<%=inputName%>', <%=affectCheckboxes %>)">&nbsp;
    312               </td>
    313               <td><base:button
    314                   title="Browse&hellip;"
    315                   onclick="<%="browseOnClick('"+inputName+"', '" + HTML.javaScriptEncode(extension) + "', "+ affectCheckboxes + ")"%>"
    316                   disabled="<%=deniedFile || deniedPlatform %>"
    317                   />
    318               </td>
    319             </tr>
    320             </table>
    321           </td>
    322         </tr>
    323         <tr>
    324           <td align="right"></td>
    325           <td>
    326           <%
    327           if (recentFiles != null && recentFiles.size() > 0)
    328           {
    329             %>
    330             <select name="recent.<%=inputName%>" onchange="recentOnChange('<%=inputName%>', <%=affectCheckboxes%>)">
    331             <option value="">- recently used -
    332             <option value="">- clear -
    333             <%
    334             for (File recent : recentFiles)
     479            if (!isPartOfPlatform && !deniedPlatform)
    335480            {
     481              hasNonPlatformFiles = true;
    336482              %>
    337               <option value="<%=recent.getId()%>"><%=HTML.encodeTags(recent.getPath().toString())%>
     483              <base:icon image="warning.gif" tooltip="This file is not part of the platform/subtype" />
    338484              <%
    339485            }
    340486            %>
    341             </select>
     487          </td>
     488          <td class="file" id="filelist.<%=dftId%>.file">
    342489            <%
    343           }
    344           %>
     490            if (files == null || files.size() == 0)
     491            {
     492              %>
     493              <div id="filelist.<%=dftId%>.0">
     494              <i>- not selected -</i>
     495              </div>
     496              <%
     497            }
     498            else
     499            {
     500              for (FileSetMember fm : files)
     501              {
     502                File file = fm.getFile();
     503                %>
     504                <div id="filelist.<%=dftId%>.<%=file.getId() %>">
     505                <%=file.getPath() %>
     506                </div>
     507                <%
     508              }
     509              %>
     510              <%
     511            }
     512            %>
    345513          </td>
     514          <td class="fileaction">
     515            <base:icon image="mini_scroll_down.png"
     516              visible="<%=recentFiles.size() >= 0 %>"
     517              tooltip="Select a recently used file"
     518              onclick="<%="recentFilesOnClick(event, " + dftId + ")"%>"
     519            />
     520              <div id="recentfiles.<%=dftId%>" style="display: none;" class="recentfiles">
     521                <div class="recentfile"
     522                  onclick="selectRecentFile(<%=dftId%>, 0)"
     523                  id="recentfile.<%=dftId%>.0"
     524                  ><i>- not selected -</i></div>
     525                <%
     526                for (File recent : recentFiles)
     527                {
     528                  %>
     529                  <div class="recentfile"
     530                    onclick="selectRecentFile(<%=dftId%>, <%=recent.getId()%>)"
     531                    id="recentfile.<%=dftId%>.<%=recent.getId()%>"
     532                    ><%=HTML.encodeTags(recent.getPath().toString())%></div>
     533                  <%
     534                }
     535                %>
     536              </div>
     537          </td>
     538          <td class="fileaction">
     539            <base:icon image="add.png"
     540              onclick="<%="addFilesOnClick("+dftId+", '" + HTML.javaScriptEncode(extension) + "', "+ affectCheckboxes + ")"%>"
     541              visible="<%=allowMultiple %>"
     542            />
     543            <base:icon image="browse.png"
     544              onclick="<%="browseOnClick("+dftId+", '" + HTML.javaScriptEncode(extension) + "', "+ affectCheckboxes + ")"%>"
     545              visible="<%=!allowMultiple%>"
     546            />
     547          </td>
     548          <!--
     549          <td class="fileaction">
     550            <base:icon image="remove.png"
     551              id="remove"
     552              onclick="<%="removeOnClick("+dftId+", "+ affectCheckboxes + ")"%>"
     553              visible="<%=!allowMultiple %>"
     554            />
     555          </td>
     556          -->
    346557        </tr>
    347558        <%
    348       }
    349       if (validationSupport)
    350       {
    351       %>
    352       <tr>
    353         <td class="prompt">Validate</td>
    354         <td><input type="checkbox" value="1" <%=activateCheckBoxes ? "" : "disabled"%> name="datafiles.validate"></td>
    355       </tr>
    356       <%
    357559      }
    358560      %>
    359561      </table>
    360562      <%
    361       if (hasNonPlatformFiles)
    362       {
    363         if (platform != null)
    364         {
     563    }
     564    %>
     565    </div>
     566
     567      <form name="datafiles">
     568      <table width="100%">
     569      <tr>
     570        <td>
     571          <%
     572          if (validationSupport)
     573          {
     574            %>
     575            <b>Validate</b>
     576            <input type="checkbox" value="1" disabled name="datafiles.validate">
     577            <%
     578          }
    365579          %>
    366           <div align="right">
    367           <base:icon image="warning.gif" />
    368           = The file type is not part of the <i><%=HTML.encodeTags(platform.getName())%></i> platform
    369           </div>
     580        </td>
     581        <td>
    370582          <%
    371         }
    372         else if (itemSubtype != null)
    373         {
     583          if (hasNonPlatformFiles)
     584          {
     585            if (platform != null)
     586            {
     587              %>
     588              <div align="right">
     589              <base:icon image="warning.gif" />
     590              = The file type is not part of the <i><%=HTML.encodeTags(platform.getName())%></i> platform
     591              </div>
     592              <%
     593            }
     594            else if (itemSubtype != null)
     595            {
     596              %>
     597              <div align="right">
     598              <base:icon image="warning.gif" />
     599              = The file type is not part of the <i><%=HTML.encodeTags(itemSubtype.getName())%></i> subtype
     600              </div>
     601              <%
     602            }
     603          }
    374604          %>
    375           <div align="right">
    376           <base:icon image="warning.gif" />
    377           = The file type is not part of the <i><%=HTML.encodeTags(itemSubtype.getName())%></i> subtype
    378           </div>
    379           <%
    380         }
    381       }
    382     }
    383     %>
    384 
     605        </td>
     606      </table>
    385607    </form>
    386    
     608    <a href="javascript:writeFileActions()">See</a>
    387609  </base:body>
    388610  </base:page>
  • trunk/www/filemanager/files/list_files.jsp

    r5666 r5713  
    342342      Table.submitToPopup(formId, cmd, 740, 540);
    343343    }
    344     function returnSelected()
     344    function returnSelected(element)
    345345    {
    346346      var frm = document.forms[formId];
    347       updateSelected(Forms.getCheckedRadio(frm.item_id));
    348       // Table.returnSelected(formId, <%=callback != null ? "window.top.opener."+callback : "null" %>);
    349       window.top.returnSelected();
    350       window.top.close();
     347      updateSelected(element);
     348      if (element.type == 'radio')
     349      {
     350        window.top.returnSelected();
     351        window.top.close();
     352      }
    351353    }
    352354    function presetOnChange()
     
    355357    }
    356358
    357     function updateSelected(radio)
    358     {
    359       window.top.setSelected(radio.value, radio.title);
    360       //window.top.document.forms[0].file.value = radio.title;
    361     }
     359    function updateSelected(element)
     360    {
     361      if (element.type == 'radio')
     362      {
     363        window.top.setSelected(element.value, element.title);
     364      }
     365      else if (element.type == 'checkbox')
     366      {
     367        if (element.checked)
     368        {
     369          window.top.addSelected(element.value, element.title);
     370        }
     371        else
     372        {
     373          window.top.removeSelected(element.value);
     374        }
     375      }
     376    }
     377
     378   
    362379    function moveToDirectory(directoryId, path)
    363380    {
     
    10111028                    name="<%=itemId%>"
    10121029                    value="<%=itemId%>"
    1013                     title="<%=name%>"
    1014                     <%=cc.getSelected().contains(itemId) ? "checked" : ""%>
     1030                    title="<%=tagPath%>"
     1031                    <%=cc.getSelected().contains(itemId) ? "checked" : ""%>
     1032                    onclick="updateSelected(this)"
    10151033                  ></tbl:header>
    10161034                <tbl:header
  • trunk/www/filemanager/index.jsp

    r5630 r5713  
    6767    // Display the list page after updating the current context from the request parameters
    6868    Base.getAndSetCurrentContext(sc, itemType, pageContext, defaultContext);
    69     forward = "select_file.jsp";
     69    forward = "select_file.jsp?mode=selectone";
     70  }
     71  else if ("SelectMultiple".equals(cmd))
     72  {
     73    // Display the list page after updating the current context from the request parameters
     74    Base.getAndSetCurrentContext(sc, itemType, pageContext, defaultContext);
     75    forward = "select_file.jsp?mode=selectmultiple";
    7076  }
    7177  else if ("SaveAs".equals(cmd))
  • trunk/www/filemanager/select_file.jsp

    r5426 r5713  
    3535String requestTitle = request.getParameter("title");
    3636String callback = request.getParameter("callback");
    37 
     37final ModeInfo mode = ModeInfo.get(request.getParameter("mode"));
     38final String title = mode.generateTitle("file", "files");
    3839%>
    39 <base:page title="<%=requestTitle == null ? "Select one file" : requestTitle%>" type="popup">
     40<base:page title="<%=requestTitle == null ? title : requestTitle%>" type="popup">
    4041<base:head >
    4142  <script language="JavaScript">
     
    5859    // Find the browser window height
    5960    var windowHeight = Main.getWindowHeight();
    60     iframeElement.height = windowHeight-offsetTop-100;
     61    var controlsPos = Main.getElementPosition(document.getElementById('controls'));
     62    iframeElement.height = windowHeight-offsetTop - controlsPos.height - 15;
    6163
    6264    // Adjust the height of the frames
     
    8284    frm.path.value = path;
    8385  }
     86  function addSelected(fileId, path)
     87  {
     88    var frm = document.forms['file'];
     89    if (getSelectedFileIndex(fileId) == -1)
     90    {
     91      frm.paths[frm.paths.length] = new Option(path, fileId);
     92    }
     93  }
     94  function removeSelected(fileId)
     95  {
     96    var frm = document.forms['file'];
     97    var index = getSelectedFileIndex(fileId);
     98    if (index >= 0) frm.paths[index] = null;
     99  }
     100 
     101  function getSelectedFileIndex(fileId)
     102  {
     103    var frm = document.forms['file'];
     104    for (var i = 0; i < frm.paths.length; i++)
     105    {
     106      if (frm.paths[i].value == fileId) return i;
     107    }
     108    return -1;
     109  }
    84110 
    85111  function returnSelected()
    86112  {
    87113    var frm = document.forms['file'];
    88     if (frm.file_id.value)
     114    <%
     115    if (mode == ModeInfo.SELECTONE)
    89116    {
    90       window.opener.<%=callback%>(frm.file_id.value, frm.path.value);
     117      %>
     118      if (frm.file_id.value)
     119      {
     120        window.opener.<%=callback%>(frm.file_id.value, frm.path.value);
     121      }
     122      <%
    91123    }
     124    else
     125    {
     126      %>
     127      for (var i = 0; i < frm.paths.length; i++)
     128      {
     129        window.opener.<%=callback%>(frm.paths[i].value, frm.paths[i].text);
     130      }
     131      <%
     132    }
     133    %>   
    92134    window.close();
    93135  }
     
    95137</base:head>
    96138<base:body attributes="onresize='setTimer();'">
    97   <h3><%=requestTitle == null ? "Select one file" : requestTitle%></h3>
    98   <iframe name="manager" id="idManager" src="frameset.jsp?ID=<%=ID%>&mode=selectone" width="100%"
     139  <h3><%=requestTitle == null ? title : requestTitle%></h3>
     140  <iframe name="manager" id="idManager" src="frameset.jsp?ID=<%=ID%>&mode=<%=mode.getName()%>" width="100%"
    99141    frameborder="0" vspace="0" hspace="0"
    100142    marginwidth="0" marginheight="0" scrolling="no" style="overflow: visible"></iframe>
    101143
    102   <div style="border-top: 1px solid #666666" >
     144  <div style="border-top: 1px solid #666666" id="controls">
    103145  <form name="file">
    104146  <input type="hidden" name="file_id" value="">
    105  
    106   <p>
    107147  <table class="form" align="center">
    108   <tr>
    109     <td class="prompt">Selected file</td>
    110     <td><input type="text" class="text" name="path" size="100" value=""></td>
    111   </tr>
     148  <%
     149  if (mode == ModeInfo.SELECTONE)
     150  {
     151    %>
     152    <tr>
     153      <td class="prompt">Selected file</td>
     154      <td><input type="text" class="text" name="path" size="100" value=""></td>
     155    </tr>
     156    <%
     157  }
     158  else
     159  {
     160    %>
     161    <tr>
     162      <td class="prompt">Selected files</td>
     163      <td><select name="paths" size="5" multiple style="width: 50em;"></select></td>
     164    </tr>
     165    <%
     166  }
     167  %>
    112168  </table>
    113169  </form>
    114   </div>
    115170 
    116171  <table align="center">
     
    120175  </tr>
    121176  </table>
     177  </div>
    122178</base:body>
    123179</base:page>
  • trunk/www/include/scripts/table.js

    r5643 r5713  
    417417    if (mode == 'selectone')
    418418    {
    419       Forms.checkRadio(frm.item_id, itemId);
    420       returnFunction();
     419      var index = Forms.checkRadio(frm.item_id, itemId);
     420      returnFunction(frm.item_id[index]);
    421421    }
    422422    else if (mode == 'selectmultiple' || mode == 'selectmultiplenobuttons')
    423423    {
    424       this.toggleCheckBox(tableId, itemId);
     424      var checkbox = this.toggleCheckBox(tableId, itemId);
     425      returnFunction(checkbox);
    425426    }
    426427    else
     
    446447      {
    447448        element.checked = !element.checked;
    448       }
    449     }
     449        return element;
     450      }
     451    }
     452    return null;
    450453  }
    451454
  • trunk/www/views/derivedbioassays/edit_bioassay.jsp

    r5701 r5713  
    297297        if (dataFilesLoaded)
    298298        {
    299           Platforms.addDataFilesToForm(frames.datafiles, frm);
     299          //Platforms.addDataFilesToForm(frames.datafiles, frm);
     300          frames.datafiles.writeFileActionsToForm(frm);
    300301        }
    301302        if (frm.isRoot)
Note: See TracChangeset for help on using the changeset viewer.