Changeset 6082


Ignore:
Timestamp:
Aug 14, 2012, 3:54:00 PM (11 years ago)
Author:
Nicklas Nordborg
Message:

References #1707: Make it possible for a derived bioassay to have multiple physical bioassays as parents

Changed the database schema and implemented API methods for this. The web GUI has been updated, but some things are still broken. Eg. it is not possible to select an extract (will fix this in #1708) or inherit annotations correctly. Item overview and batch importers have not been fixed.

Code for updating an existing installation is also missing, so do not try this since it will probably break several things and cause data loss.

Location:
trunk
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/core/common-queries.xml

    r6037 r6082  
    13971397      SELECT {1}
    13981398      FROM DerivedBioAssayData dba
    1399       WHERE dba.physicalBioAssay = :bioAssay
    1400       AND dba.parent is null
     1399      INNER JOIN dba.physicalBioAssays pba
     1400      WHERE pba = :bioAssay
     1401      AND dba.root = true
    14011402    </sql>
    14021403    <description>
     
    14101411      SELECT {1}
    14111412      FROM DerivedBioAssayData dba
    1412       WHERE dba.parent = :bioAssay
     1413      INNER JOIN dba.parents p
     1414      WHERE p = :bioAssay
    14131415    </sql>
    14141416    <description>
  • trunk/src/core/net/sf/basedb/core/DerivedBioAssay.java

    r5749 r6082  
    2222package net.sf.basedb.core;
    2323
     24import java.util.ArrayList;
    2425import java.util.Collection;
    25 import java.util.Collections;
    2626import java.util.Date;
    2727import java.util.HashSet;
     
    2929
    3030import net.sf.basedb.core.data.ArrayBatchData;
     31import net.sf.basedb.core.data.ArrayDesignData;
    3132import net.sf.basedb.core.data.ArraySlideData;
    3233import net.sf.basedb.core.data.DerivedBioAssayData;
     
    9899 
    99100  /**
     101    Create a new parent-less derived bioassay. Parent items can be
     102    added by calling {@link #addPhysicalBioAssay(PhysicalBioAssay)} or
     103    {@link #addParent(DerivedBioAssay)}.
     104    @param dc The <code>DbControl</code> which will be used for
     105      permission checking and database access
     106    @param isRoot TRUE if the new item is a root derived bioassay
     107      (eg. it have physical bioassays as parent items)
     108    @param job The job that created the new bioassay
     109    @return A new DerivedBioAssay item
     110    @since 3.2
     111  */
     112  public static DerivedBioAssay getNew(DbControl dc, boolean isRoot, Job job)
     113  {
     114    DerivedBioAssay dbas = dc.newItem(DerivedBioAssay.class);
     115    dbas.setName("New derived bioassay");
     116    dbas.getData().setRoot(isRoot);
     117    dbas.getData().setEntryDate(new Date());
     118    dbas.getData().setJob(job == null ? null : job.getData());
     119    return dbas;
     120   
     121  }
     122 
     123  /**
    100124    Create a new (root) derived bioassay from a physical bioassay.
    101125    @param dc The <code>DbControl</code> which will be used for
     
    107131  public static DerivedBioAssay getNew(DbControl dc, PhysicalBioAssay bioAssay, Job job)
    108132  {
    109     if (bioAssay == null) throw new InvalidUseOfNullException("bioAssay");
    110     bioAssay.checkPermission(Permission.USE);
    111    
    112     DerivedBioAssay dbas = dc.newItem(DerivedBioAssay.class);
    113     dbas.setName("New derived bioassay");
    114     dbas.getData().setPhysicalBioAssay(bioAssay.getData());
    115     dbas.getData().setEntryDate(new Date());
    116     dbas.getData().setJob(job == null ? null : job.getData());
     133    DerivedBioAssay dbas = getNew(dc, true, job);
     134    dbas.addPhysicalBioAssay(bioAssay);
    117135    return dbas;
    118136  }
     
    128146  public static DerivedBioAssay getNew(DbControl dc, DerivedBioAssay parent, Job job)
    129147  {
    130     if (parent == null) throw new InvalidUseOfNullException("parent");
    131     parent.checkPermission(Permission.USE);
    132    
    133     DerivedBioAssay dbas = dc.newItem(DerivedBioAssay.class);
    134     dbas.setName("New derived bioassay");
    135     dbas.getData().setParent(parent.getData());
    136     dbas.getData().setPhysicalBioAssay(parent.getData().getPhysicalBioAssay());
    137     dbas.getData().setExtract(parent.getData().getExtract());
    138     dbas.getData().setEntryDate(new Date());
    139     dbas.getData().setJob(job == null ? null : job.getData());
     148    DerivedBioAssay dbas = getNew(dc, false, job);
     149    dbas.addParent(parent);
    140150    return dbas;
    141151  }
     
    238248        SELECT {1}
    239249        FROM DerivedBioAssayData dba
    240         WHERE dba.parent = :bioAssay
     250        INNER JOIN dba.parents p
     251        WHERE p = :bioAssay
    241252      */
    242253      query.setEntity("bioAssay", this.getData());
     
    295306  */
    296307  /**
    297     Get the extract and parent bioassay set or physical bioassay.
     308    Get the extract and parent bioassays or physical bioassays.
    298309  */
    299310  @Override
     
    306317      if (isRoot())
    307318      {
    308         annotatable.add(getPhysicalBioAssay());
     319        ItemQuery<PhysicalBioAssay> query = getPhysicalBioAssays();
     320        query.include(Include.ALL);
     321        annotatable.addAll(query.list(getDbControl()));
    309322      }
    310323      else
    311324      {
    312         annotatable.add(getParent());
     325        ItemQuery<DerivedBioAssay> query = getParents();
     326        query.include(Include.ALL);
     327        annotatable.addAll(query.list(getDbControl()));
    313328      }
    314329      if (getData().getExtract() != null) annotatable.add(getExtract());
     
    394409  public Collection<FileSet> getParentFileSets()
    395410  {
    396     DerivedBioAssay parent = getParent();
     411    ItemQuery<DerivedBioAssay> query = getParents();
     412    query.include(Include.ALL);
    397413    Collection<FileSet> parents = null;
    398     if (parent != null && parent.hasFileSet())
    399     {
    400       parents = Collections.singleton(parent.getFileSet());
     414    for (DerivedBioAssay parent : query.list(getDbControl()))
     415    {
     416      if (parent.hasFileSet())
     417      {
     418        if (parents == null) parents = new ArrayList<FileSet>();
     419        parents.add(parent.getFileSet());
     420      }
    401421    }
    402422    return parents;
     
    408428    bioassay set. This property is always inherited down to child events
    409429    so this method never return null.
    410   */
     430    @deprecated In 3.2, replaced with {@link #getPhysicalBioAssays()}.
     431    @return Always null
     432  */
     433  @Deprecated
    411434  public PhysicalBioAssay getPhysicalBioAssay()
    412435  {
    413     return getDbControl().getItem(PhysicalBioAssay.class, getData().getPhysicalBioAssay());
    414   }
     436    return null;
     437  }
     438 
     439  /**
     440    Add a physical bioassay as a parent to this derived bioassay.
     441    Note! Physical bioassays can only be added if this derived bioassay
     442    is a root bioassay. The physical bioassay for non-root derived
     443    bioassays are automatically assigned.
     444    @param bioAssay The parent bioassay to add
     445    @since 3.2
     446  */
     447  public void addPhysicalBioAssay(PhysicalBioAssay bioAssay)
     448    throws PermissionDeniedException, InvalidDataException
     449  {
     450    checkPermission(Permission.WRITE);
     451    if (!isRoot()) throw new PermissionDeniedException("Can't add physical bioassay to non-root derived bioassay");
     452    if (bioAssay == null) throw new InvalidUseOfNullException("bioAssay");
     453    bioAssay.checkPermission(Permission.USE);
     454    getData().getPhysicalBioAssays().add(bioAssay.getData());
     455  }
     456 
     457  /**
     458    Remove a physical bioassay as a parent item for this derived
     459    bioassay.
     460    Note! Physical bioassays can only be removed if this derived bioassay
     461    is a root bioassay. The physical bioassay for non-root derived
     462    bioassays are automatically assigned.
     463    @param bioAssay The parent bioassay to remove from this bioassay
     464    @since 3.2
     465  */
     466  public void removePhysicalBioAssay(PhysicalBioAssay bioAssay)
     467    throws PermissionDeniedException, InvalidDataException
     468  {
     469    checkPermission(Permission.WRITE);
     470    if (!isRoot()) throw new PermissionDeniedException("Can't remove physical bioassay from non-root derived bioassay");
     471    if (bioAssay == null) throw new InvalidUseOfNullException("bioAssay");
     472    getData().getPhysicalBioAssays().remove(bioAssay.getData());
     473  }
     474 
     475  /**
     476    Get a query that returns the physical bioassays used to create
     477    this derived bioassay.
     478    @return An <code>ItemQuery</code> object
     479    @since 3.2
     480  */
     481  public ItemQuery<PhysicalBioAssay> getPhysicalBioAssays()
     482  {
     483    ItemQuery<PhysicalBioAssay> query = PhysicalBioAssay.getQuery();
     484    query.joinPermanent(Hql.innerJoin("derivedBioAssays", Item.DERIVEDBIOASSAY.getAlias()));
     485    query.restrictPermanent(
     486      Restrictions.eq(
     487        Hql.alias(Item.DERIVEDBIOASSAY.getAlias()),
     488        Hql.entity(this)
     489      )
     490    );
     491    return query;
     492  }
     493
    415494 
    416495  /**
    417496    Get the parent derived bioassay set.   
    418497    @return The parent bioassay set or null if this item is a root bioassay set
    419   */
     498    @deprecated In 3.2, replaced with {@link #getParents()}
     499    @return Always null
     500  */
     501  @Deprecated
    420502  public DerivedBioAssay getParent()
    421503  {
    422     return getDbControl().getItem(DerivedBioAssay.class, getData().getParent());
    423   }
    424 
    425   /**
    426     Check if this bioassay set is derived from a physical bioassay or from another
    427     bioassay set.
     504    return null;
     505  }
     506
     507 
     508  /**
     509    Add a derived bioassay as a parent to this derived bioassay.
     510    Note! Derived bioassays can only be added if this derived bioassay
     511    is not a root bioassay. The physical bioassays are automatically assigned.
     512    @param bioAssay The parent bioassay to add
     513    @since 3.2
     514  */
     515  public void addParent(DerivedBioAssay bioAssay)
     516    throws PermissionDeniedException, InvalidDataException
     517  {
     518    checkPermission(Permission.WRITE);
     519    if (isRoot()) throw new PermissionDeniedException("Root derived bioassays can't have parent derived bioassays");
     520    if (bioAssay == null) throw new InvalidUseOfNullException("bioAssay");
     521    if (this.equals(bioAssay)) throw new InvalidDataException("Can't add self as parent: " + this);
     522    bioAssay.checkPermission(Permission.USE);
     523    getData().getParents().add(bioAssay.getData());
     524    getData().getPhysicalBioAssays().addAll(bioAssay.getData().getPhysicalBioAssays());
     525  }
     526
     527  /**
     528    Remove a derived bioassay as a parent item for this derived
     529    bioassay.
     530    Note! Derived bioassays can only be used as parents if this derived bioassay
     531    is not a root bioassay. The physical bioassays are automatically assigned.
     532    @param bioAssay The parent bioassay to remove from this bioassay
     533    @since 3.2
     534  */
     535  public void removeParent(DerivedBioAssay bioAssay)
     536    throws PermissionDeniedException, InvalidDataException
     537  {
     538    checkPermission(Permission.WRITE);
     539    if (isRoot()) throw new PermissionDeniedException("Root derived bioassays can't have parent derived bioassays");
     540    if (bioAssay == null) throw new InvalidUseOfNullException("bioAssay");
     541    getData().getParents().remove(bioAssay.getData());
     542  }
     543
     544 
     545  /**
     546    Get all parent derived bioassays.
     547    @return A query returning all parent bioassays
     548    @since 3.2
     549  */
     550  public ItemQuery<DerivedBioAssay> getParents()
     551  {
     552    ItemQuery<DerivedBioAssay> query = DerivedBioAssay.getQuery();
     553    query.joinPermanent(Hql.innerJoin("children", "c"));
     554    query.restrictPermanent(
     555      Restrictions.eq(
     556        Hql.alias("c"),
     557        Hql.entity(this)
     558      )
     559    );
     560    return query;
     561  }
     562
     563 
     564  /**
     565    Check if this bioassay set is derived from one or more physical bioassays or
     566    from derived bioassays. A root derived bioassay can only have physical bioassays
     567    as parent items. A non-root derived bioassay can only have other derived
     568    bioassays as parents, but the core keep automatically keep track of the
     569    physical bioassays.
    428570    @return TRUE if this is a root bioassay set derived form a physical bioassay
    429571  */
    430572  public boolean isRoot()
    431573  {
    432     return getData().getParent() == null;
     574    return getData().isRoot();
    433575  }
    434576 
     
    466608  {
    467609    ItemQuery<DerivedBioAssay> query = DerivedBioAssay.getQuery();
     610    query.joinPermanent(Hql.innerJoin("parents", "p"));
    468611    query.restrictPermanent(
    469612      Restrictions.eq(
    470         Hql.property("parent"),
     613        Hql.alias("p"),
    471614        Hql.entity(this)
    472615      )
     
    571714    Get the array design connected to this derived bioassay by
    572715    following the path from the physical bioassay to the array slide to
    573     the array batch  to the array design.
     716    the array batch  to the array design. If this derived bioasay
     717    has multiple parents that are linked to different array designs,
     718    null is returned.
    574719    @return The array design, or null if no array design is connected
    575720    @throws PermissionDeniedException If the logged in user doesn't have
     
    580725    throws PermissionDeniedException, BaseException
    581726  {
    582     PhysicalBioAssayData pba = getData().getPhysicalBioAssay();
    583     if (pba == null) return null;
    584     ArraySlideData slide = pba.getArraySlide();
    585     if (slide == null) return null;
    586     ArrayBatchData batch = slide.getArrayBatch();
    587     if (batch == null) return null;
    588     return getDbControl().getItem(ArrayDesign.class, batch.getArrayDesign());
     727    ArrayDesignData uniqueDesign = null;
     728    for (PhysicalBioAssayData pba : getData().getPhysicalBioAssays())
     729    {
     730      ArraySlideData slide = pba.getArraySlide();
     731      if (slide == null) continue;
     732     
     733      ArrayBatchData batch = slide.getArrayBatch();
     734      if (batch == null) continue;
     735     
     736      ArrayDesignData design = batch.getArrayDesign();
     737      if (design == null) continue;
     738     
     739      if (uniqueDesign == null)
     740      {
     741        // First array design we see is (temporarily) accepted as the one to return
     742        uniqueDesign = design;
     743      }
     744      else
     745      {
     746        // If the design are different, break out and return null
     747        if (!design.equals(uniqueDesign)) return null;
     748      }
     749    }
     750   
     751    return getDbControl().getItem(ArrayDesign.class, uniqueDesign);
    589752  }
    590753
  • trunk/src/core/net/sf/basedb/core/Install.java

    r6079 r6082  
    119119    method.
    120120  */
    121   public static final int NEW_SCHEMA_VERSION = Integer.valueOf(108).intValue();
     121  public static final int NEW_SCHEMA_VERSION = Integer.valueOf(109).intValue();
    122122 
    123123  public static synchronized int createTables(SchemaGenerator.Mode mode, ProgressReporter progress,
  • trunk/src/core/net/sf/basedb/core/PhysicalBioAssay.java

    r5983 r6082  
    235235        SELECT {1}
    236236        FROM DerivedBioAssayData dba
    237         WHERE dba.physicalBioAssay = :bioAssay
    238         AND dba.parent is null
     237        INNER JOIN dba.physicalBioAssays pba
     238        WHERE pba = :bioAssay
     239        AND dba.root = true
    239240      */
    240241    query.setEntity("bioAssay", this.getData());
     
    441442  {
    442443    ItemQuery<DerivedBioAssay> query = DerivedBioAssay.getQuery();
    443     query.restrictPermanent(
    444       Restrictions.eq(
    445         Hql.property("physicalBioAssay"),
    446         Hql.entity(this)
    447       )
    448     );
    449     query.restrictPermanent(Restrictions.eq(Hql.property("parent"), null));
     444    query.joinPermanent(Hql.innerJoin("physicalBioAssays", "pba"));
     445    query.restrictPermanent(Restrictions.eq(Hql.alias("pba"), Hql.entity(this)));
     446    query.restrictPermanent(Restrictions.eq(Hql.property("root"), Expressions.bool(true)));
    450447    return query;
    451448  }
     
    467464      SELECT {1}
    468465      FROM DerivedBioAssayData dba
    469       WHERE dbs.physicalBioAssay = :bioAssay
    470       AND dba.parent is null
     466      INNER JOIN dba.physicalBioAssays pba
     467      WHERE pba = :bioAssay
     468      AND dba.root = true
    471469    */
    472470    query.setEntity("bioAssay", this.getData());
  • trunk/src/core/net/sf/basedb/core/Update.java

    r6061 r6082  
    143143  </tr>
    144144  <tr>
    145     <td>107</td>
     145    <td>108</td>
    146146    <td>
    147147      Added {@link BioPlateData#getSection()}, {@link BioPlateData#getTray()}
    148148      and {@link BioPlateData#getPosition()}
    149149      All existing bioplates get null values.
     150    </td>
     151  </tr>
     152  <tr>
     153    <td>109</td>
     154    <td>
     155      Added {@link DerivedBioAssayData#getPhysicalBioAssays()} and {@link DerivedBioAssayData#getParents()}
     156      and removed <code>DerivedBioAssayData.getPhysicalBioAssay()</code> and
     157      <code>DerivedBioAssayData.getParent()</code>. Existing derived bioassays are updated.
    150158    </td>
    151159  </tr>
     
    238246        schemaVersion = setSchemaVersionInTransaction(session, 108);
    239247        progress_current += 2 * progress_step;
     248      }
     249     
     250      if (schemaVersion < 109)
     251      {
     252        if (progress != null) progress.display((int)(progress_current), "--Updating schema version: " + schemaVersion + " -> 109...");
     253        schemaVersion = updateToSchemaVersion109(session);
     254        progress_current += progress_step;
    240255      }
    241256
     
    606621    return schemaVersion;
    607622  }
     623 
     624  /**
     625    Move derived bioassay parent items to different tables. Get rid of
     626    old columns in the DerivedBioAssays table.
     627   
     628    @return The new schema version (=109)
     629  */
     630  private static int updateToSchemaVersion109(org.hibernate.Session session)
     631    throws BaseException
     632  {
     633    final int schemaVersion = 109;
     634    try
     635    {
     636 
     637      // TODO - 1707
     638     
     639      // Update the schema version number
     640      setSchemaVersionInTransaction(session, schemaVersion);
     641 
     642      log.info("updateToSchemaVersion109: OK");
     643    }
     644    catch (BaseException ex)
     645    {
     646      log.error("updateToSchemaVersion109: FAILED", ex);
     647      throw ex;
     648    }
     649    return schemaVersion;
     650  }
     651
    608652 
    609653  // Item type codes for item types that was removed since BASE 2
     
    13151359        DerivedBioAssayData bioAssay = new DerivedBioAssayData();
    13161360        bioAssay.setEntryDate((Date)row[2]);
    1317         bioAssay.setPhysicalBioAssay(load(session, PhysicalBioAssayData.class, hybMap.get(row[3])));
     1361        bioAssay.setRoot(true);
     1362        bioAssay.getPhysicalBioAssays().add(load(session, PhysicalBioAssayData.class, hybMap.get(row[3])));
    13181363        bioAssay.setHardware(load(session, HardwareData.class, row[4]));
    13191364        bioAssay.setProtocol(load(session, ProtocolData.class, row[5]));
  • trunk/src/core/net/sf/basedb/core/data/DerivedBioAssayData.java

    r5818 r6082  
    11/**
    2   $Id: DerivedBioAssayData.java 5685 2011-08-04 10:58:23Z nicklas $
     2  $Id$
    33
    44  Copyright (C) 2011 Nicklas Nordborg
     
    2323
    2424import java.util.Date;
     25import java.util.HashSet;
    2526import java.util.Set;
    2627
     
    2930  @author Nicklas
    3031  @since 3.0
    31   @base.modified $Date: 2011-08-04 12:58:23 +0200 (to, 04 aug 2011) $
     32  @base.modified $Date$
    3233  @hibernate.class table="`DerivedBioAssays`" lazy="true"
    3334  @see <a href="../../../../../../html/developer/api/data_api.bioassays.html">Developer documentation: Bioassays and raw data</a>
     
    9091  // -------------------------------------------
    9192
    92   private PhysicalBioAssayData bioAssay;
    93   /**
    94     Get the physical bioassay that is the direct or indirect parent bioassay set.
    95     @hibernate.many-to-one column="`bioassay_id`" not-null="true" update="false" outer-join="false"
    96   */
    97   public PhysicalBioAssayData getPhysicalBioAssay()
    98   {
    99     return bioAssay;
    100   }
    101   public void setPhysicalBioAssay(PhysicalBioAssayData bioAssay)
    102   {
    103     this.bioAssay = bioAssay;
    104   }
    105 
    106   private DerivedBioAssayData parent;
    107   /**
    108     Get the bioassay that is the parent of this bioassay. Null if this bioassay was
    109     created from a physical bioassay.
    110     @hibernate.many-to-one column="`parent_id`" not-null="false" update="false" outer-join="false"
    111   */
    112   public DerivedBioAssayData getParent()
    113   {
    114     return parent;
    115   }
    116   public void setParent(DerivedBioAssayData parent)
    117   {
    118     this.parent = parent;
     93  private boolean isRoot;
     94  /**
     95    A flag indicating if this is a root derived bioassay or not. A root
     96    bioassay can only have physical bioassays as parents, while a non-root
     97    bioassay only can have other derived bioassays as parents (but the
     98    physical bioassays collection should be automatically managed to reflect
     99    the parents of the parents, etc.)
     100    @since 3.2
     101    @hibernate.property column="`is_root`" type="boolean" not-null="true"
     102  */
     103  public boolean isRoot()
     104  {
     105    return isRoot;
     106  }
     107  public void setRoot(boolean isRoot)
     108  {
     109    this.isRoot = isRoot;
     110  }
     111 
     112  private Set<PhysicalBioAssayData> physicalBioAssays;
     113  /**
     114    A set that manages the parent physical bioassays that this derived bioassay
     115    is related to.
     116    @since 3.2
     117    @hibernate.set table="`ParentPhysicalBioAssays`" lazy="true"
     118    @hibernate.collection-key column="`derivedbioassay_id`"
     119    @hibernate.collection-many-to-many column="`physicalbioassay_id`" class="net.sf.basedb.core.data.PhysicalBioAssayData"
     120  */
     121  public Set<PhysicalBioAssayData> getPhysicalBioAssays()
     122  {
     123    if (physicalBioAssays == null) physicalBioAssays = new HashSet<PhysicalBioAssayData>();
     124    return physicalBioAssays;
     125  }
     126 
     127  void setPhysicalBioAssays(Set<PhysicalBioAssayData> physicalBioAssays)
     128  {
     129    this.physicalBioAssays = physicalBioAssays;
     130  }
     131 
     132  private Set<DerivedBioAssayData> parents;
     133  /**
     134    A set that manages the parent bioassays that this derived bioassay
     135    related to.
     136    @since 3.2
     137    @hibernate.set table="`ParentDerivedBioAssays`" lazy="true"
     138    @hibernate.collection-key column="`derivedbioassay_id`"
     139    @hibernate.collection-many-to-many column="`parentbioassay_id`" class="net.sf.basedb.core.data.DerivedBioAssayData"
     140  */
     141  public Set<DerivedBioAssayData> getParents()
     142  {
     143    if (parents == null) parents = new HashSet<DerivedBioAssayData>();
     144    return parents;
     145  }
     146  void setParents(Set<DerivedBioAssayData> parents)
     147  {
     148    this.parents = parents;
    119149  }
    120150
     
    122152  /**
    123153    This is the inverse end.
    124     @see DerivedBioAssayData#getParent()
    125     @hibernate.set lazy="true" inverse="true"
    126     @hibernate.collection-key column="`parent_id`"
    127     @hibernate.collection-one-to-many class="net.sf.basedb.core.data.DerivedBioAssayData"
     154    @see DerivedBioAssayData#getParents()
     155    @hibernate.set table="`ParentDerivedBioAssays`" lazy="true" inverse="true"
     156    @hibernate.collection-key column="`parentbioassay_id`"
     157    @hibernate.collection-many-to-many column="`derivedbioassay_id`" class="net.sf.basedb.core.data.DerivedBioAssayData"
    128158  */
    129159  Set<DerivedBioAssayData> getChildren()
  • trunk/src/core/net/sf/basedb/core/data/PhysicalBioAssayData.java

    r5818 r6082  
    105105  }
    106106
     107 
    107108  private Set<DerivedBioAssayData> rootDerivedBioAssays;
    108109  /**
    109110    This is the inverse end with an extra restriction
    110111    @see DerivedBioAssayData#getPhysicalBioAssay()
    111     @hibernate.set lazy="true" inverse="true" where="`parent_id` is null"
    112     @hibernate.collection-key column="`bioassay_id`"
    113     @hibernate.collection-one-to-many class="net.sf.basedb.core.data.DerivedBioAssayData"
     112    @hibernate.set table="`ParentPhysicalBioAssays`" lazy="true" inverse="true"
     113    @hibernate.collection-key column="`physicalbioassay_id`"
     114    @hibernate.collection-many-to-many column="`derivedbioassay_id`" class="net.sf.basedb.core.data.DerivedBioAssayData" where="`is_root`"
    114115  */
    115116  Set<DerivedBioAssayData> getRootDerivedBioAssays()
     
    125126  /**
    126127    This is the inverse end.
    127     @see DerivedBioAssayData#getPhysicalBioAssay()
    128     @hibernate.set lazy="true" inverse="true"
    129     @hibernate.collection-key column="`bioassay_id`"
    130     @hibernate.collection-one-to-many class="net.sf.basedb.core.data.DerivedBioAssayData"
     128    @see DerivedBioAssayData#getPhysicalBioAssays()
     129    @hibernate.set table="`ParentPhysicalBioAssays`" lazy="true" inverse="true"
     130    @hibernate.collection-key column="`physicalbioassay_id`"
     131    @hibernate.collection-many-to-many column="`derivedbioassay_id`" class="net.sf.basedb.core.data.DerivedBioAssayData"
    131132  */
    132133  Set<DerivedBioAssayData> getDerivedBioAssays()
  • trunk/src/test/TestDerivedBioAssay.java

    r5748 r6082  
    5555   
    5656    // Children and bioassays
    57     int child1 = test_create_child("Child #1", id, 0, 0, 0, 0, 0);
    58     int child2 = test_create_child("Child #2", id, 0, 0, 0, 0, 0);
     57    int child1 = test_create_child("Child #1", 0, 0, 0, 0, 0, id);
     58    int child2 = test_create_child("Child #2", 0, 0, 0, 0, 0, id);
    5959
    6060    // Listing
     
    6767    TestDataFileType.test_set_file(Item.DERIVEDBIOASSAY, child1, DataFileType.SAM, samId);
    6868   
     69    // A more complex setup:
     70    // Extract #1 and #2 get four child items
     71    // Two of each are put on two different physical bioassays
     72    // A derived bioassay is created for each child extract (2+2=4)
     73    // Two merged derived bioassays are created (one for each extract)
     74    int tag1 = TestTag.test_create("T1", SystemItems.getId(Tag.BARCODE), false);
     75    int tag2 = TestTag.test_create("T2", SystemItems.getId(Tag.BARCODE), false);
     76   
     77    int e1a1 = TestExtract.test_create(extractId1, "Extract #1.a1", SystemItems.getId(Extract.LIBRARY), tag1, false);
     78    int e1a2 = TestExtract.test_create(extractId1, "Extract #1.a2", SystemItems.getId(Extract.LIBRARY), tag1, false);
     79    int e1a3 = TestExtract.test_create(extractId1, "Extract #1.a3", SystemItems.getId(Extract.LIBRARY), tag1, false);
     80    int e1a4 = TestExtract.test_create(extractId1, "Extract #1.a4", SystemItems.getId(Extract.LIBRARY), tag1, false);
     81    int e2a1 = TestExtract.test_create(extractId2, "Extract #2.a1", SystemItems.getId(Extract.LIBRARY), tag2, false);
     82    int e2a2 = TestExtract.test_create(extractId2, "Extract #2.a2", SystemItems.getId(Extract.LIBRARY), tag2, false);
     83    int e2a3 = TestExtract.test_create(extractId2, "Extract #2.a3", SystemItems.getId(Extract.LIBRARY), tag2, false);
     84    int e2a4 = TestExtract.test_create(extractId2, "Extract #2.a4", SystemItems.getId(Extract.LIBRARY), tag2, false);
     85   
     86    int flowCell1 = TestPhysicalBioAssay.test_create(0, "Flow cell #1", SystemItems.getId(PhysicalBioAssay.CLONAL_AMPLIFICATION), 2);
     87    TestPhysicalBioAssay.test_add_extract(flowCell1, e1a1, 1, null);
     88    TestPhysicalBioAssay.test_add_extract(flowCell1, e1a2, 2, null);
     89    TestPhysicalBioAssay.test_add_extract(flowCell1, e2a1, 1, null);
     90    TestPhysicalBioAssay.test_add_extract(flowCell1, e2a2, 2, null);
     91
     92    int flowCell2 = TestPhysicalBioAssay.test_create(0, "Flow cell #2", SystemItems.getId(PhysicalBioAssay.CLONAL_AMPLIFICATION), 2);
     93    TestPhysicalBioAssay.test_add_extract(flowCell2, e1a3, 1, null);
     94    TestPhysicalBioAssay.test_add_extract(flowCell2, e1a4, 2, null);
     95    TestPhysicalBioAssay.test_add_extract(flowCell2, e2a3, 1, null);
     96    TestPhysicalBioAssay.test_add_extract(flowCell2, e2a4, 2, null);
     97
     98    // Root derived bioassay -> one per flow cell
     99    int root1 = test_create_root("Seq #1", flowCell1, SystemItems.getId(DerivedBioAssay.SEQUENCES), 0, 0, 0);
     100    int root2 = test_create_root("Seq #2", flowCell2, SystemItems.getId(DerivedBioAssay.SEQUENCES), 0, 0, 0);
     101   
     102    // First child derived bioassay -> one per aliquot
     103    int ARRANGEMENT = SystemItems.getId(DerivedBioAssay.ARRANGEMENT);
     104    int bam1l1t1 = test_create_child("BAM #1.lane1.tag1", e1a1, ARRANGEMENT, 0, 0, 0, root1);
     105    int bam1l1t2 = test_create_child("BAM #1.lane1.tag2", e2a1, ARRANGEMENT, 0, 0, 0, root1);
     106    int bam1l2t1 = test_create_child("BAM #1.lane2.tag1", e1a2, ARRANGEMENT, 0, 0, 0, root1);
     107    int bam1l2t2 = test_create_child("BAM #1.lane2.tag2", e2a2, ARRANGEMENT, 0, 0, 0, root1);
     108
     109    int bam2l1t1 = test_create_child("BAM #2.lane1.tag1", e1a3, ARRANGEMENT, 0, 0, 0, root2);
     110    int bam2l1t2 = test_create_child("BAM #2.lane1.tag2", e2a3, ARRANGEMENT, 0, 0, 0, root2);
     111    int bam2l2t1 = test_create_child("BAM #2.lane2.tag1", e1a4, ARRANGEMENT, 0, 0, 0, root2);
     112    int bam2l2t2 = test_create_child("BAM #2.lane2.tag2", e2a4, ARRANGEMENT, 0, 0, 0, root2);
     113   
     114    // Merged child derived bioassay -> one per original extract
     115    int merged1 = test_create_child("Extract #1.merged", extractId1, ARRANGEMENT, 0, 0, 0, bam1l1t1, bam1l2t1, bam2l1t1, bam2l2t1);
     116    int merged2 = test_create_child("Extract #2.merged", extractId2, ARRANGEMENT, 0, 0, 0, bam1l1t2, bam1l2t2, bam2l1t2, bam2l2t2);
     117   
    69118    // Standard test: Delete
    70119    if (TestUtil.waitBeforeDelete()) TestUtil.waitForEnter();
     120   
     121    test_delete(merged1);
     122    test_delete(merged2);
     123    test_delete(bam1l1t1);
     124    test_delete(bam1l1t2);
     125    test_delete(bam1l2t1);
     126    test_delete(bam1l2t2);
     127    test_delete(bam2l1t1);
     128    test_delete(bam2l1t2);
     129    test_delete(bam2l2t1);
     130    test_delete(bam2l2t2);
     131    test_delete(root1);
     132    test_delete(root2);
     133    TestPhysicalBioAssay.test_delete(flowCell1);
     134    TestPhysicalBioAssay.test_delete(flowCell2);
     135   
     136    TestExtract.test_delete(e1a1);
     137    TestExtract.test_delete(e1a2);
     138    TestExtract.test_delete(e1a3);
     139    TestExtract.test_delete(e1a4);
     140    TestExtract.test_delete(e2a1);
     141    TestExtract.test_delete(e2a2);
     142    TestExtract.test_delete(e2a3);
     143    TestExtract.test_delete(e2a4);
     144   
     145    TestTag.test_delete(tag1);
     146    TestTag.test_delete(tag2);
     147   
    71148    test_delete(child1);
    72149    test_delete(child2);
     
    132209  }
    133210
    134   static int test_create_child(String name, int parentId, int extractId, int subtypeId,
    135       int protocolId, int hardwareId, int softwareId)
    136   {
    137     if (parentId == 0) return 0;
     211  static int test_create_child(String name, int extractId, int subtypeId,
     212      int protocolId, int hardwareId, int softwareId, int... parents)
     213  {
     214    if (parents == null || parents.length == 0) return 0;
    138215    int id = 0;
    139216    DbControl dc = null;
     
    141218    {
    142219      dc = TestUtil.getDbControl();
    143       DerivedBioAssay dbas = DerivedBioAssay.getNew(dc, DerivedBioAssay.getById(dc, parentId), null);
     220      DerivedBioAssay dbas = DerivedBioAssay.getNew(dc, false, null);
    144221      dbas.setName(name);
    145222      dbas.setDescription("Added at "+new Date());
     223      for (int parentId: parents)
     224      {
     225        dbas.addParent(DerivedBioAssay.getById(dc, parentId));
     226      }
     227     
    146228      if (extractId != 0)
    147229      {
  • trunk/src/test/TestTag.java

    r5662 r6082  
    6868      dc = TestUtil.getDbControl();
    6969      Tag t = Tag.getNew(dc);
     70      t.setName(name);
     71      if (subtypeId != 0)
     72      {
     73        t.setItemSubtype(ItemSubtype.getById(dc, subtypeId));
     74      }
    7075      if (setAll)
    7176      {
    72         t.setName("Test tag");
    7377        t.setDescription("Added at "+new Date());
    7478      }
  • trunk/www/views/derivedbioassays/edit_bioassay.jsp

    r5967 r6082  
    3737  import="net.sf.basedb.core.ItemResultList"
    3838  import="net.sf.basedb.core.Include"
     39  import="net.sf.basedb.core.Type"
     40  import="net.sf.basedb.core.query.Expressions"
    3941  import="net.sf.basedb.core.query.Orders"
    4042  import="net.sf.basedb.core.query.Hql"
     43  import="net.sf.basedb.core.query.Restrictions"
    4144  import="net.sf.basedb.core.PermissionDeniedException"
    4245  import="net.sf.basedb.core.BaseException"
     
    7376  ItemSubtype currentSubtype = null;
    7477
    75   boolean readCurrentPhysicalBioAssay = true;
    76   PhysicalBioAssay currentPhysicalBioAssay = null;
    77  
    78   boolean readCurrentParentBioAssay = true;
    79   DerivedBioAssay currentParentBioAssay = null;
    80  
    8178  boolean readCurrentExtract = true;
    8279  Extract currentExtract = null;
     
    9188  Software currentSoftware = null;
    9289
     90  ItemQuery<PhysicalBioAssay> physicalQuery = null;
     91  ItemQuery<DerivedBioAssay> parentQuery = null;
     92 
     93  Item parentType = null;
     94 
    9395  if (itemId == 0)
    9496  {
    9597    title = "New derived bioassay";
    9698    cc.removeObject("item");
     99    int parentId = Values.getInt(request.getParameter("parent_id"));
     100    int physicalBioAssayId = Values.getInt(request.getParameter("physicalbioassay_id"));
    97101    int currentSubtypeId = Values.getInt(request.getParameter("subtype_id"));
    98102    List<ItemSubtype> relatedToParent = Collections.emptyList();
    99     int parentId = Values.getInt(request.getParameter("parent_id"));
     103   
    100104    if (parentId != 0)
    101105    {
    102       currentParentBioAssay = DerivedBioAssay.getById(dc, parentId);
     106      parentType = Item.DERIVEDBIOASSAY;
     107      DerivedBioAssay dba = DerivedBioAssay.getById(dc, parentId);
     108      parentQuery = DerivedBioAssay.getQuery();
     109      parentQuery.restrict(Restrictions.eq(Hql.property("id"), Expressions.integer(parentId)));
    103110      if (currentSubtypeId == 0)
    104111      {
    105         relatedToParent = ItemSubtype.getParentSubtypes(dc, currentParentBioAssay, Item.DERIVEDBIOASSAY);
    106       }
    107       try
    108       {
    109         currentPhysicalBioAssay = currentParentBioAssay.getPhysicalBioAssay();
    110       }
    111       catch (PermissionDeniedException ex)
    112       {
    113         readCurrentPhysicalBioAssay = false;
    114       }
    115       try
    116       {
    117         currentExtract = currentParentBioAssay.getExtract();
    118       }
    119       catch (PermissionDeniedException ex)
    120       {}
    121     }
    122     else
    123     {
    124       int physicalBioAssayId = Values.getInt(request.getParameter("physicalbioassay_id"));
    125       if (physicalBioAssayId != 0)
    126       {
    127         currentPhysicalBioAssay = PhysicalBioAssay.getById(dc, physicalBioAssayId);
    128         if (currentSubtypeId == 0)
    129         {
    130           relatedToParent = ItemSubtype.getParentSubtypes(dc, currentPhysicalBioAssay, Item.DERIVEDBIOASSAY);
    131         }
    132       }
    133     }
     112        relatedToParent = ItemSubtype.getParentSubtypes(dc, dba, Item.DERIVEDBIOASSAY);
     113      }
     114    }
     115    else if (physicalBioAssayId != 0)
     116    {
     117      parentType = Item.PHYSICALBIOASSAY;
     118      PhysicalBioAssay pba = PhysicalBioAssay.getById(dc, physicalBioAssayId);
     119      physicalQuery = PhysicalBioAssay.getQuery();
     120      physicalQuery.restrict(Restrictions.eq(Hql.property("id"), Expressions.integer(physicalBioAssayId)));
     121      if (currentSubtypeId == 0)
     122      {
     123        relatedToParent = ItemSubtype.getParentSubtypes(dc, pba, Item.DERIVEDBIOASSAY);
     124      }
     125    }
     126    else if ("PHYISCALBIOASSAY".equals(request.getParameter("useParents")))
     127    {
     128      parentType = Item.PHYSICALBIOASSAY;
     129      physicalQuery = PhysicalBioAssay.getQuery();
     130      physicalQuery.restrict(Restrictions.in(Hql.property("id"), Expressions.parameter("selected")));
     131      physicalQuery.setParameter("selected", sc.getCurrentContext(Item.PHYSICALBIOASSAY).getSelected(), Type.INT);
     132    }
     133    else if ("DERIVEDBIOASSAY".equals(request.getParameter("useParents")))
     134    {
     135      parentType = Item.DERIVEDBIOASSAY;
     136      parentQuery = DerivedBioAssay.getQuery();
     137      parentQuery.restrict(Restrictions.in(Hql.property("id"), Expressions.parameter("selected")));
     138      parentQuery.setParameter("selected", cc.getSelected(), Type.INT);
     139    }
     140
    134141    if (currentSubtypeId == 0)
    135142    {
     
    155162    title = "Edit bioassay -- " + HTML.encodeTags(bioAssay.getName());
    156163   
     164    if (bioAssay.isRoot())
     165    {
     166      physicalQuery = bioAssay.getPhysicalBioAssays();
     167      parentType = Item.PHYSICALBIOASSAY;
     168    }
     169    else
     170    {
     171      parentQuery = bioAssay.getParents();
     172      parentType = Item.DERIVEDBIOASSAY;
     173    }
     174   
    157175    try
    158176    {
     
    162180    {
    163181      readCurrentSubtype = false;
    164     }
    165     try
    166     {
    167       currentParentBioAssay = bioAssay.getParent();
    168     }
    169     catch (PermissionDeniedException ex)
    170     {
    171       readCurrentParentBioAssay = false;
    172     }
    173     try
    174     {
    175       currentPhysicalBioAssay = bioAssay.getPhysicalBioAssay();
    176     }
    177     catch (PermissionDeniedException ex)
    178     {
    179       readCurrentPhysicalBioAssay = false;
    180182    }
    181183    try
     
    227229
    228230  // Load recently used items
    229   List<PhysicalBioAssay> recentPhysicalBioAssays = (List<PhysicalBioAssay>)cc.getRecent(dc, Item.PHYSICALBIOASSAY);
    230   List<DerivedBioAssay> recentParentBioAssays = (List<DerivedBioAssay>)cc.getRecent(dc, Item.DERIVEDBIOASSAY);
    231231  List<Protocol> recentProtocols = (List<Protocol>)cc.getRecent(dc, Item.PROTOCOL, currentSubtype);
    232232  List<Hardware> recentHardware = (List<Hardware>)cc.getRecent(dc, Item.HARDWARE, currentSubtype);
     
    243243  %>
    244244  <base:page type="popup" title="<%=title%>">
    245   <base:head scripts="tabcontrol.js,annotations.js,platforms.js,subtypes.js,ajax.js,json2.js" styles="tabcontrol.css">
     245  <base:head scripts="tabcontrol.js,annotations.js,platforms.js,subtypes.js,ajax.js,json2.js,linkitems.js" styles="tabcontrol.css">
    246246    <ext:scripts context="<%=jspContext%>" />
    247247    <ext:stylesheets context="<%=jspContext%>" />
     
    257257        return false;
    258258      }
    259       if (frm.isRoot)
    260       {
    261         if (frm.isRoot[0].checked)
    262         {
    263           if (frm.physicalbioassay_id.selectedIndex < 0)
    264           {
    265             alert("You must select a parent bioassay");
    266             frm.physicalbioassay_id.focus();
    267             return false;
    268           }
    269         }
    270         else
    271         {
    272           if (frm.parent_id.selectedIndex < 0)
    273           {
    274             alert("You must select a parent bioassay");
    275             frm.parent_id.focus();
    276             return false;
    277           }
    278         }
    279        
    280       }
    281259      return true;
    282260    }
     
    300278          frames.datafiles.writeFileActionsToForm(frm);
    301279        }
    302         if (frm.isRoot)
    303         {
    304           if (frm.isRoot[0].checked)
    305           {
    306             frm.parent_id.selectedIndex = -1;
    307           }
    308           else
    309           {
    310             frm.physicalbioassay_id.selectedIndex = -1;
    311           }
     280        if (frm.addedPhysicalBioAssays)
     281        {
     282          frm.addedPhysicalBioAssays.value = Link.getActionIds(1, 'P').join(',');
     283          frm.removedPhysicalBioAssays.value = Link.getActionIds(-1, 'P').join(',');
     284        }
     285        if (frm.addedParents)
     286        {
     287          frm.addedParents.value = Link.getActionIds(1, 'D').join(',');
     288          frm.removedParents.value = Link.getActionIds(-1, 'D').join(',');
    312289        }
    313290        frm.submit();
     
    362339    {
    363340      var frm = document.forms['bioAssay'];
    364       if (!frm.physicalbioassay_id) return;
    365341     
    366342      var parents = new Array();
    367343      if (frm.isRoot[0].checked)
    368344      {
    369         var bioAssayId = Math.abs(parseInt(frm.physicalbioassay_id[frm.physicalbioassay_id.selectedIndex].value));
    370         if (bioAssayId > 0) parents[parents.length] = 'PHYSICALBIOASSAY:'+bioAssayId;
     345        var ids = Link.getListIds(frm.physicalBioAssays, 'P');
     346        if (ids.length > 0)
     347        {
     348          parents[parents.length] = 'PHYSICALBIOASSAY:'+ids.join(':');
     349        }
    371350      }
    372351      else
    373352      {
    374         var bioAssayId = Math.abs(parseInt(frm.parent_id[frm.parent_id.selectedIndex].value));
    375         if (bioAssayId > 0) parents[parents.length] = 'DERIVEDBIOASSAY:'+bioAssayId;
     353        var ids = Link.getListIds(frm.parents, 'D');
     354        if (ids.length > 0)
     355        {
     356          parents[parents.length] = 'DERIVEDBIOASSAY:'+ids.join(':');
     357        }
    376358      }
    377359      return parents;
     
    459441      url += '&callback=setParentBioAssayCallback&resetTemporary=1';
    460442      url += ItemSubtype.createRelatedFilter('bioAssay', 'DERIVEDBIOASSAY');
    461       if (frm.parent_id.selectedIndex >= 0)
    462       {
    463         var id = Math.abs(parseInt(frm.parent_id[frm.parent_id.selectedIndex].value));       
     443      if (frm.parents.selectedIndex >= 0)
     444      {
     445        var id = Math.abs(parseInt(frm.parents[frm.parents.selectedIndex].value));       
    464446        url += '&item_id='+id;
    465447      }
     
    469451    {
    470452      var frm = document.forms['bioAssay'];
    471       var list = frm.parent_id;
     453      var list = frm.parents;
    472454      if (list.length < 1 || list[0].value == '0') // >
    473455      {
     
    536518    }
    537519
     520    function addPhysicalBioAssayOnClick()
     521    {
     522      var frm = document.forms['bioAssay'];
     523      var url = '../physicalbioassays/index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectmultiple';
     524      url += '&callback=addPhysicalBioAssayCallback&resetTemporary=1';
     525      url += ItemSubtype.createRelatedFilter('bioAssay', 'PHYSICALBIOASSAY');
     526      Main.openPopup(url, 'AddPhysicalBioAssay', 1050, 700);
     527    }
     528   
     529    function addPhysicalBioAssayCallback(pbaId, name)
     530    {
     531      var frm = document.forms['bioAssay'];
     532      var item = Link.getItem('P', pbaId);
     533      if (!item) item = new Item('P', pbaId, name);
     534      Link.addItem(frm.physicalBioAssays, item);
     535      parentsChanged = true;
     536    }
     537
     538    function addParentOnClick()
     539    {
     540      var frm = document.forms['bioAssay'];
     541      var url = 'index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectmultiple';
     542      url += '&callback=addParentCallback&resetTemporary=1';
     543      url += ItemSubtype.createRelatedFilter('bioAssay', 'DERIVEDBIOASSAY');
     544      Main.openPopup(url, 'AddParentBioAssay', 1050, 700);
     545    }
     546   
     547    function addParentCallback(dbaId, name)
     548    {
     549      var frm = document.forms['bioAssay'];
     550      var item = Link.getItem('D', dbaId);
     551      if (!item) item = new Item('D', dbaId, name);
     552      Link.addItem(frm.parents, item);
     553      parentsChanged = true;
     554    }
     555   
    538556    function init()
    539557    {
     
    548566      }
    549567      %>
     568      initParents();
     569      initPhysicalBioAssays();
    550570      if (frm.isRoot)
    551571      {
     
    556576        initExtracts();
    557577      }
     578    }
     579   
     580    function initPhysicalBioAssays()
     581    {
     582      var physicalBioAssays = document.forms['bioAssay'].physicalBioAssays;
     583      <%
     584      if (physicalQuery != null)
     585      {
     586        physicalQuery.include(Include.ALL);
     587        physicalQuery.order(Orders.asc(Hql.property("name")));
     588        ItemResultList<PhysicalBioAssay> physicalBioAssays = physicalQuery.list(dc);
     589        for (PhysicalBioAssay pba : physicalBioAssays)
     590        {
     591          if (bioAssay != null)
     592          {
     593            %>
     594            Link.addNewItem(physicalBioAssays, new Item('P', <%=pba.getId()%>, '<%=HTML.javaScriptEncode(pba.getName())%>'));
     595            <%
     596          }
     597          else
     598          {
     599            %>
     600            Link.addItem(physicalBioAssays, new Item('P', <%=pba.getId()%>, '<%=HTML.javaScriptEncode(pba.getName())%>'));
     601            <%
     602          }
     603        }
     604      }
     605      %>
     606    }
     607   
     608    function initParents()
     609    {
     610      var parents = document.forms['bioAssay'].parents;
     611      <%
     612      if (parentQuery != null)
     613      {
     614        parentQuery.include(Include.ALL);
     615        parentQuery.order(Orders.asc(Hql.property("name")));
     616        ItemResultList<DerivedBioAssay> parents = parentQuery.list(dc);
     617        for (DerivedBioAssay dba : parents)
     618        {
     619          if (bioAssay != null)
     620          {
     621            %>
     622            Link.addNewItem(parents, new Item('D', <%=dba.getId()%>, '<%=HTML.javaScriptEncode(dba.getName())%>'));
     623            <%
     624          }
     625          else
     626          {
     627            %>
     628            Link.addItem(parents, new Item('D', <%=dba.getId()%>, '<%=HTML.javaScriptEncode(dba.getName())%>'));
     629            <%
     630          }
     631        }
     632      }
     633      %>
    558634    }
    559635   
     
    593669      else
    594670      {
    595         if (currentParentBioAssay != null)
     671        if (bioAssay.isRoot())
    596672        {
    597673          %>
    598           extracts = getExtractsFromParentBioassay(<%=currentParentBioAssay.getId()%>);
     674          extracts = getExtractsFromPhysicalBioAssays();
    599675          <%
    600676        }
    601         else if (currentPhysicalBioAssay != null)
     677        else
    602678        {
    603679          %>
    604           extracts = getExtractsFromPhysicalBioAssay(<%=currentPhysicalBioAssay.getId()%>);
     680          extracts = getExtractsFromParentBioassays();
    605681          <%
    606682        }
     
    742818          <td>
    743819            <input id="isRoot" type="radio" name="isRoot" value="1"
    744               <%=currentParentBioAssay == null ? "checked" : "" %>
     820              <%=parentType == Item.PHYSICALBIOASSAY ? "checked" : "" %>
    745821              onchange="isRootOnChange()"><label for="isRoot">Physical bioassay</label>
    746822            <input id="isChild" type="radio" name="isRoot" value="0"
    747               <%=currentParentBioAssay == null ? "" : "checked" %>
     823              <%=parentType != Item.PHYSICALBIOASSAY ? "checked" : "" %>
    748824              onchange="isRootOnChange()"><label for="isChild">Derived bioassay</label><br>
    749825          </td>
    750826          <td></td>
    751827        </tr>
    752         <tr id="physicalBioAssaySection" style="display: none;">
    753           <th class="subprompt">- physical bioassay</th>
     828        <%
     829      }
     830      %>
     831      <%
     832      if (bioAssay == null || bioAssay.isRoot())
     833      {
     834        %>
     835        <tr id="physicalBioAssaySection">
     836          <th class="subprompt">- physical bioassays</th>
    754837          <td>
    755             <base:select
    756               id="physicalbioassay_id"
    757               clazz="selectionlist unchangeable"
    758               required="true"
    759               current="<%=currentPhysicalBioAssay%>"
    760               recent="<%=recentPhysicalBioAssays%>"
    761               newitem="true"
    762               onselect="selectPhysicalBioAssayOnClick()"
    763               onchange="physicalBioAssayOnChange()"
    764             />
     838            <div class="selectionlist">
     839            <table>
     840            <tr>
     841            <td>
     842              <select name="physicalBioAssays" size="4" multiple onchange="physicalBioAssayOnChange()">
     843              </select>
     844            </td>
     845            <td>
     846            <td style="vertical-align: top;">
     847              <base:buttongroup vertical="true">
     848                <base:button
     849                  subclass="leftaligned"
     850                  style="width: 12em;"
     851                  onclick="addPhysicalBioAssayOnClick()"
     852                  title="Add&nbsp;bioassays&hellip;"
     853                  tooltip="Add physical bioassays"
     854                />
     855                <base:button
     856                  subclass="leftaligned"
     857                  style="width: 12em;"
     858                  onclick="removePhysicalBioAssayOnClick()"
     859                  title="Remove"
     860                  tooltip="Remove the selected physical bioassays"
     861                />
     862              </base:buttongroup>
     863              <input type="hidden" name="addedPhysicalBioAssays" value="">
     864              <input type="hidden" name="removedPhysicalBioAssays" value="">
     865            </td>
     866            </tr>
     867            </table>
     868            </div>
    765869          </td>
    766870          <td></td>
    767871        </tr>
    768         <tr id="parentBioAssaySection" style="display: none;">
    769           <th class="subprompt">- bioassay</th>
     872        <%
     873      }
     874      if (bioAssay == null || !bioAssay.isRoot())
     875      {
     876        %>
     877        <tr id="parentBioAssaySection">
     878          <th class="subprompt">- bioassays</th>
    770879          <td>
    771             <base:select
    772               id="parent_id"
    773               clazz="selectionlist unchangeable"
    774               required="true"
    775               current="<%=currentParentBioAssay%>"
    776               recent="<%=recentParentBioAssays%>"
    777               newitem="true"
    778               onselect="selectParentBioAssayOnClick()"
    779               onchange="parentBioAssayOnChange()"
    780             />
     880            <div class="selectionlist">
     881            <table>
     882            <tr>
     883            <td>
     884              <select name="parents" size="4" multiple onchange="parentsOnChange()">
     885              </select>
     886            </td>
     887            <td>
     888            <td style="vertical-align: top;">
     889              <base:buttongroup vertical="true">
     890                <base:button
     891                  subclass="leftaligned"
     892                  style="width: 12em;"
     893                  onclick="addParentOnClick()"
     894                  title="Add&nbsp;bioassays&hellip;"
     895                  tooltip="Add parent derived bioassays"
     896                />
     897                <base:button
     898                  subclass="leftaligned"
     899                  style="width: 12em;"
     900                  onclick="removeParentOnClick()"
     901                  title="Remove"
     902                  tooltip="Remove the selected derived bioassays"
     903                />
     904              </base:buttongroup>
     905              <input type="hidden" name="addedParents" value="">
     906              <input type="hidden" name="removedParents" value="">
     907            </td>
     908            </tr>
     909            </table>
     910            </div>
     911           
    781912          </td>
    782913          <td></td>
  • trunk/www/views/derivedbioassays/index.jsp

    r6040 r6082  
    179179    if (bas == null)
    180180    {
    181       int parentId = Values.getInt(request.getParameter("parent_id"));
    182       int physicalBioAssayId = Values.getInt(request.getParameter("physicalbioassay_id"));
    183       if (parentId == 0)
    184       {
    185         PhysicalBioAssay bioAssay = PhysicalBioAssay.getById(dc, physicalBioAssayId);
    186         bas = DerivedBioAssay.getNew(dc, bioAssay, null);
    187         cc.setRecent(bioAssay, maxRecent);
    188       }
    189       else
    190       {
    191         DerivedBioAssay parent = DerivedBioAssay.getById(dc, parentId);
    192         bas = DerivedBioAssay.getNew(dc, parent, null);
    193         cc.setRecent(parent, maxRecent);
    194       }
     181      bas = DerivedBioAssay.getNew(dc, Values.getBoolean(request.getParameter("isRoot")), null);
    195182      dc.saveItem(bas);
    196183      message = "Derived bioassay created";
     
    247234        bas.setSoftware(sw);
    248235        if (sw != null) cc.setRecent(sw, subtype, maxRecent);
     236      }
     237     
     238      if (bas.isRoot())
     239      {
     240        // A root derived bioassay set may have physical bioassays as parents
     241        String[] removePhysicalBioAssays = Values.getString(request.getParameter("removedPhysicalBioAssays")).split(",");
     242        for (int i = 0; i < removePhysicalBioAssays.length; ++i)
     243        {
     244          int pbaId = Values.getInt(removePhysicalBioAssays[i], -1);
     245          if (pbaId != -1) bas.removePhysicalBioAssay(PhysicalBioAssay.getById(dc, pbaId));
     246        }
     247       
     248        String[] addPhysicalBioAssays = Values.getString(request.getParameter("addedPhysicalBioAssays")).split(",");
     249        for (int i = 0; i < addPhysicalBioAssays.length; ++i)
     250        {
     251          int pbaId = Values.getInt(addPhysicalBioAssays[i], -1);
     252          if (pbaId != -1) bas.addPhysicalBioAssay(PhysicalBioAssay.getById(dc, pbaId));
     253        }
     254      }
     255      else
     256      {
     257        // A non-root derived bioassay set may have other derived bioassays as parents
     258        String[] removeParents = Values.getString(request.getParameter("removedParents")).split(",");
     259        for (int i = 0; i < removeParents.length; ++i)
     260        {
     261          int parentId = Values.getInt(removeParents[i], -1);
     262          if (parentId != -1) bas.removeParent(DerivedBioAssay.getById(dc, parentId));
     263        }
     264       
     265        String[] addParents = Values.getString(request.getParameter("addedParents")).split(",");
     266        for (int i = 0; i < addParents.length; ++i)
     267        {
     268          int parentId = Values.getInt(addParents[i], -1);
     269          if (parentId != -1) bas.addParent(DerivedBioAssay.getById(dc, parentId));
     270        }
    249271      }
    250272     
     
    422444    redirect = "../../common/plugin/index.jsp?ID="+ID+"&cmd=SelectPlugin&item_type="+itemType.name()+"&context_type=ITEM&main_type=ANALYZE&title=Run+analysis+plugin";
    423445  }
     446  else if ("NewMergedDerivedBioAssay".equals(cmd))
     447  {
     448    ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, pageContext, defaultContext);
     449    cc.setId(0);
     450    forward = editPage + "&useParents=DERIVEDBIOASSAY";
     451  }
    424452  else
    425453  {
  • trunk/www/views/derivedbioassays/list_bioassays.jsp

    r6040 r6082  
    9595  final ItemQuery<ItemSubtype> subtypesQuery = Base.getSubtypesQuery(itemType);
    9696
     97  // Query for parent physical bioassays to the current bioassay
     98  final ItemQuery<PhysicalBioAssay> physicalBioAssayQuery = PhysicalBioAssay.getQuery();
     99  physicalBioAssayQuery.include(cc.getInclude());
     100  physicalBioAssayQuery.join(Hql.innerJoin("derivedBioAssays", "dba"));
     101  physicalBioAssayQuery.restrict(Restrictions.eq(Hql.alias("dba"), Expressions.parameter("bioAssay")));
     102  physicalBioAssayQuery.order(Orders.asc(Hql.property("name")));
     103
     104  // Query for parent bioassays to the current bioassay
     105  final ItemQuery<DerivedBioAssay> parentQuery = DerivedBioAssay.getQuery();
     106  parentQuery.include(cc.getInclude());
     107  parentQuery.join(Hql.innerJoin("children", "c"));
     108  parentQuery.restrict(Restrictions.eq(Hql.alias("c"), Expressions.parameter("bioAssay")));
     109  parentQuery.order(Orders.asc(Hql.property("name")));
     110
    97111  // Query for child bioassays to the current bioassay
    98112  final ItemQuery<DerivedBioAssay> childQuery = DerivedBioAssay.getQuery();
    99113  childQuery.include(cc.getInclude());
    100   childQuery.restrict(Restrictions.eq(Hql.property("parent"), Expressions.parameter("bioAssay")));
     114  childQuery.join(Hql.innerJoin("parents", "p"));
     115  childQuery.restrict(Restrictions.eq(Hql.alias("p"), Expressions.parameter("bioAssay")));
    101116  childQuery.order(Orders.asc(Hql.property("name")));
    102117
     
    213228      Main.viewOrEditItem('<%=ID%>', 'RAWBIOASSAY', 0, true, '&bioassay_id='+parentId);
    214229    }
     230    function newMergedChild()
     231    {
     232      var frm = document.forms[formId];
     233      Table.poolItems(submitPage, '<%=ID%>', formId, '<%=itemType.name()%>', 'NewMergedDerivedBioAssay');
     234    }
    215235    </script>
    216236  </base:head>
     
    271291      />
    272292      <tbl:columndef
    273         id="physicalBioAssay"
    274         property="physicalBioAssay.name"
    275         datatype="string"
    276         title="Physical bioassay"
    277         sortable="true"
    278         filterable="true"
    279         exportable="true"
    280       />
    281       <tbl:columndef
    282         id="parent"
    283         property="parent.name"
    284         datatype="string"
    285         title="Parent bioassay"
    286         sortable="true"
     293        id="physicalBioAssays"
     294        property="&physicalBioAssays(name)"
     295        datatype="string"
     296        title="Physical bioassays"
     297        filterable="true"
     298        exportable="true"
     299      />
     300      <tbl:columndef
     301        id="parents"
     302        property="&parents(name)"
     303        datatype="string"
     304        title="Parent bioassays"
    287305        filterable="true"
    288306        exportable="true"
     
    437455            title="New&hellip;"
    438456            tooltip="<%=createPermission ? "Create new derived bioassay" : "You do not have permission to create derived bioassays"%>"
     457          />
     458          <tbl:button
     459            disabled="<%=!createPermission%>"
     460            image="new_pooled.png"
     461            onclick="newMergedChild()"
     462            title="Merge&hellip;"
     463            tooltip="<%=createPermission ? "Create new merged bioassay" : "You do not have permission to create derived bioassay"%>"
    439464          />
    440465          <tbl:button
     
    678703                  />
    679704                </tbl:cell>
    680                 <tbl:cell column="physicalBioAssay"
    681                   ><base:propertyvalue
    682                     item="<%=item%>"
    683                     property="physicalBioAssay"
    684                     enableEditLink="<%=mode.hasEditLink()%>"
    685                     enablePropertyLink="<%=mode.hasPropertyLink()%>"
    686                   /></tbl:cell>
    687                 <tbl:cell column="parent"
    688                   ><base:propertyvalue
    689                     item="<%=item%>"
    690                     property="parent"
    691                     enableEditLink="<%=mode.hasEditLink()%>"
    692                     enablePropertyLink="<%=mode.hasPropertyLink()%>"
    693                   /></tbl:cell>
     705                <tbl:cell column="physicalBioAssays">
     706                  <%
     707                  physicalBioAssayQuery.setParameter("bioAssay", itemId, Type.INT);
     708                  try
     709                  {
     710                    String separator = "";
     711                    for (PhysicalBioAssay pba : physicalBioAssayQuery.list(dc))
     712                    {
     713                      out.write(separator);
     714                      if (mode.hasPropertyLink())
     715                      {
     716                        out.write(Base.getLinkedName(ID, pba, false, mode.hasEditLink()));
     717                      }
     718                      else
     719                      {
     720                        out.write(HTML.encodeTags(pba.getName()));
     721                      }
     722                      separator = ", ";
     723                    }
     724                  }
     725                  catch (Throwable t)
     726                  {
     727                    %>
     728                    <div class="error"><%=t.getMessage()%></div>
     729                    <%
     730                  }
     731                  %>             
     732                </tbl:cell>
     733                <tbl:cell column="parents">
     734                  <%
     735                  if (!item.isRoot())
     736                  {
     737                    parentQuery.setParameter("bioAssay", itemId, Type.INT);
     738                    try
     739                    {
     740                      String separator = "";
     741                      for (DerivedBioAssay dba : parentQuery.list(dc))
     742                      {
     743                        out.write(separator);
     744                        if (mode.hasPropertyLink())
     745                        {
     746                          out.write(Base.getLinkedName(ID, dba, false, mode.hasEditLink()));
     747                        }
     748                        else
     749                        {
     750                          out.write(HTML.encodeTags(dba.getName()));
     751                        }
     752                        separator = ", ";
     753                      }
     754                    }
     755                    catch (Throwable t)
     756                    {
     757                      %>
     758                      <div class="error"><%=t.getMessage()%></div>
     759                      <%
     760                    }
     761                  }
     762                  %>             
     763                </tbl:cell>
    694764                <tbl:cell column="extract"
    695765                  ><base:propertyvalue
  • trunk/www/views/derivedbioassays/view_bioassay.jsp

    r5946 r6082  
    322322      </tr>
    323323    </table>
    324     <table style="width: 100%; height: 20em;" class="bottomborder">
     324    <table style="width: 100%; height: 16em;" class="bottomborder">
    325325    <tr valign="top">
    326326      <td style="width: 50%; height: 100%;">
     
    333333          <th>Type</th>
    334334          <td><base:propertyvalue item="<%=bioAssay%>" property="itemSubtype" /></td>
    335         </tr>
    336         <tr>
    337           <th>Physical bioassay</th>
    338           <td><base:propertyvalue item="<%=bioAssay%>" property="physicalBioAssay" /></td>
    339         </tr>
    340         <tr>
    341           <th>Parent bioassay</th>
    342           <td><base:propertyvalue item="<%=bioAssay%>" property="parent" /></td>
    343335        </tr>
    344336        <tr>
     
    491483      </div>
    492484      <%
     485      ItemQuery<PhysicalBioAssay> physicalQuery = bioAssay.getPhysicalBioAssays();
     486      physicalQuery.include(Include.ALL);
     487      physicalQuery.order(Orders.asc(Hql.property("name")));
     488      ItemResultList<PhysicalBioAssay> physicalBioAssays = physicalQuery.list(dc);
     489      %>
     490      <base:section
     491        id="physicalBioAssays"
     492        title="<%="Physical bioassays (" + physicalBioAssays.size() + ")"%>"
     493        context="<%=cc%>"
     494        >
     495        <%
     496        if (physicalBioAssays.size() == 0)
     497        {
     498          %>
     499          <div class="messagecontainer note">
     500          This bioassay doesn't have any parent physical bioassays
     501          (or you don't have permission to view them).
     502          </div>
     503          <%
     504        }
     505        else
     506        {
     507          %>
     508          <tbl:table
     509            id="physicalBioAssays"
     510            columns="all"
     511            >
     512            <tbl:columndef
     513              id="name"
     514              title="Name"
     515            />
     516            <tbl:columndef
     517              id="itemSubtype"
     518              title="Type"
     519            />
     520            <tbl:columndef
     521              id="description"
     522              title="Description"
     523            />
     524            <tbl:data>
     525              <tbl:headers>
     526                <tbl:headerrow>
     527                  <tbl:columnheaders />
     528                </tbl:headerrow>
     529              </tbl:headers>           
     530              <tbl:rows>
     531              <%
     532              for (PhysicalBioAssay item : physicalBioAssays)
     533              {
     534                %>
     535                <tbl:row>
     536                  <tbl:cell column="name"><%=Base.getLinkedName(ID, item, false, true)%></tbl:cell>
     537                  <tbl:cell column="itemSubtype"><base:propertyvalue item="<%=item%>" property="itemSubtype" /></tbl:cell>
     538                  <tbl:cell column="description"><%=HTML.encodeTags(item.getDescription())%></tbl:cell>
     539                </tbl:row>
     540                <%
     541              }
     542              %>
     543              </tbl:rows>
     544            </tbl:data>
     545          </tbl:table>
     546          <%
     547        }
     548        %>
     549      </base:section>
     550      <%
     551      if (!bioAssay.isRoot())
     552      {
     553        ItemQuery<DerivedBioAssay> parentQuery = bioAssay.getParents();
     554        parentQuery.include(Include.ALL);
     555        parentQuery.order(Orders.asc(Hql.property("name")));
     556        ItemResultList<DerivedBioAssay> parents = parentQuery.list(dc);
     557        %>
     558        <base:section
     559          id="parents"
     560          title="<%="Parent bioassays (" + parents.size() + ")"%>"
     561          context="<%=cc%>"
     562          >
     563          <%
     564          if (parents.size() == 0)
     565          {
     566            %>
     567            <div class="messagecontainer note">
     568            This bioassay doesn't have any parent bioassays
     569            (or you don't have permission to view them).
     570            </div>
     571            <%
     572          }
     573          else
     574          {
     575            %>
     576            <tbl:table
     577              id="parents"
     578              columns="all"
     579              >
     580              <tbl:columndef
     581                id="name"
     582                title="Name"
     583              />
     584              <tbl:columndef
     585                id="itemSubtype"
     586                title="Type"
     587              />
     588              <tbl:columndef
     589                id="description"
     590                title="Description"
     591              />
     592              <tbl:data>
     593                <tbl:headers>
     594                  <tbl:headerrow>
     595                    <tbl:columnheaders />
     596                  </tbl:headerrow>
     597                </tbl:headers>           
     598                <tbl:rows>
     599                <%
     600                for (DerivedBioAssay item : parents)
     601                {
     602                  %>
     603                  <tbl:row>
     604                    <tbl:cell column="name"><%=Base.getLinkedName(ID, item, false, true)%></tbl:cell>
     605                    <tbl:cell column="itemSubtype"><base:propertyvalue item="<%=item%>" property="itemSubtype" /></tbl:cell>
     606                    <tbl:cell column="description"><%=HTML.encodeTags(item.getDescription())%></tbl:cell>
     607                  </tbl:row>
     608                  <%
     609                }
     610                %>
     611                </tbl:rows>
     612              </tbl:data>
     613            </tbl:table>
     614            <%
     615          }
     616          %>
     617        </base:section>
     618        <%
     619      }
    493620      ItemQuery<DerivedBioAssay> childQuery = bioAssay.getChildren();
    494621      childQuery.include(Include.ALL);
  • trunk/www/views/physicalbioassays/index.jsp

    r6040 r6082  
    417417    redirect = "../../common/plugin/index.jsp?ID="+ID+"&cmd=SelectPlugin&item_type="+itemType.name()+"&context_type=ITEM&main_type=OTHER&title=Run+plugin";
    418418  }
     419  else if ("NewMergedDerivedBioAssay".equals(cmd))
     420  {
     421    ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, pageContext, defaultContext);
     422    redirect = "../derivedbioassays/index.jsp?ID="+ID+"&cmd=NewItem&useParents=PHYISCALBIOASSAY";
     423  }
    419424  else
    420425  {
  • trunk/www/views/physicalbioassays/list_bioassays.jsp

    r6040 r6082  
    111111  final ItemQuery<DerivedBioAssay> dbasQuery = DerivedBioAssay.getQuery();
    112112  dbasQuery.include(cc.getInclude());
    113   dbasQuery.restrict(Restrictions.eq(Hql.property("physicalBioAssay"), Expressions.parameter("bioAssay")));
    114   dbasQuery.restrict(Restrictions.eq(Hql.property("parent"), null));
     113  dbasQuery.join(Hql.innerJoin("physicalBioAssays", "pba"));
     114  dbasQuery.restrict(Restrictions.eq(Hql.alias("pba"), Expressions.parameter("bioAssay")));
     115  dbasQuery.restrict(Restrictions.eq(Hql.property("root"), Expressions.bool(true)));
    115116  dbasQuery.order(Orders.asc(Hql.property("name")));
    116117  final boolean createDerivedBioAssayPermission = sc.hasPermission(Permission.CREATE, Item.DERIVEDBIOASSAY); 
     
    217218    {
    218219      Main.viewOrEditItem('<%=ID%>', 'DERIVEDBIOASSAY', 0, true, '&physicalbioassay_id='+bioAssayId);
     220    }
     221    function newMergedDerivedBioAssay()
     222    {
     223      Table.poolItems(submitPage, '<%=ID%>', formId, '<%=itemType.name()%>', 'NewMergedDerivedBioAssay');
    219224    }
    220225    </script>
     
    425430            title="New&hellip;"
    426431            tooltip="<%=createPermission ? "Create new physical bioassay" : "You do not have permission to create physical bioassays"%>"
     432          />
     433          <tbl:button
     434            disabled="<%=!createDerivedBioAssayPermission %>"
     435            image="add.png"
     436            onclick="newMergedDerivedBioAssay()"
     437            title="New derived bioassay&hellip;"
     438            tooltip="<%=createDerivedBioAssayPermission ? "Create new derived bioassay from the selected physical bioassays" : "You do not have permission to create derived bioassays"%>"
    427439          />
    428440          <tbl:button
Note: See TracChangeset for help on using the changeset viewer.