Changeset 5663


Ignore:
Timestamp:
Jun 22, 2011, 4:03:17 PM (10 years ago)
Author:
Nicklas Nordborg
Message:

References #1153: Handling short read transcript sequence data

Changed the way parent biomaterials are handled. The pooled property has been replaced with parentType instead. There are two reasons:

  1. Removing the LabeledExtract class has changed all to Extract items which are not pooled.
  2. It doesn't make sense to talk about "pooled" biomaterials when there is only a single parent.


The web gui for biosources and samples have been updated. Extracts does not work yet.

Overview loaders have been updated.

Batch importers need to be fixed. They currently assume a single parent of the parent item type.

Also added some of the button/select taglibs to provide more control over the look and feel in some cases.

Location:
trunk
Files:
1 added
35 edited
2 moved

Legend:

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

    r5384 r5663  
    2222package net.sf.basedb.clients.web.plugins;
    2323
     24import net.sf.basedb.core.BioMaterial;
    2425import net.sf.basedb.core.DbControl;
    2526import net.sf.basedb.core.Include;
     
    4849    Object parents = null;
    4950    DbControl dc = item.getDbControl();
    50     if (item.isPooled())
     51    if (item.getParentType() == null)
    5152    {
    52       ItemQuery<? extends MeasuredBioMaterial> pooledQuery = item.getCreationEvent().getSources();
    53       pooledQuery.include(Include.ALL);
    54       parents = pooledQuery.list(dc);
     53      // No parents
    5554    }
    56     else
     55    else if (item.hasSingleParent())
    5756    {
    5857      try
     
    6362      {}
    6463    }
     64    else
     65    {
     66      ItemQuery<? extends BioMaterial> pooledQuery = item.getCreationEvent().getSources();
     67      pooledQuery.include(Include.ALL);
     68      parents = pooledQuery.list(dc);
     69    }
    6570    return parents;
    6671  }
  • trunk/src/clients/web/net/sf/basedb/clients/web/taglib/Button.java

    r4937 r5663  
    175175    defaultImages.put("remove", "remove.png");
    176176    defaultImages.put("browse", "browse.png");
     177    defaultImages.put("select", "select.png");
    177178  }
    178179 
     
    316317      if (!isDisabled())
    317318      {
    318         sb.append(" onmouseover=\"this.className='").append(getClazz()).append("_hover';\"");
    319         sb.append(" onmouseout=\"this.className='").append(getClazz()).append("';\"");
     319        //sb.append(" onmouseover=\"this.className='").append(getClazz()).append("_hover';\"");
     320        //sb.append(" onmouseout=\"this.className='").append(getClazz()).append("';\"");
    320321      }
    321322    }
     
    332333        theImage = page.getRoot() + "images/" + theImage;
    333334      }
    334       sb.append("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\"><tr><td>");
     335      sb.append("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\"><tr><td style=\"width: 20px;\">");
    335336      sb.append("<img src=\"").append(theImage).append("\"");
    336337      sb.append(" border=\"0\">");
    337       sb.append("</td><td>");
     338      sb.append("</td><td style=\"text-align: left;\">");
    338339    }
    339340    sb.append(getTitle());
  • trunk/src/clients/web/net/sf/basedb/clients/web/taglib/Select.java

    r5629 r5663  
    5959      clazz=...
    6060      style=...
     61      buttonclass=...
     62      buttonstyle=...
     63      buttontitle=...
     64      buttonicon=...
    6165      required=true|false
    6266      current=...
     
    111115  </tr>
    112116  <tr>
     117    <td>buttonclass</td>
     118    <td>buttonclass</td>
     119    <td>no</td>
     120    <td>
     121      The value if this attribute goes directly into the standard HTML
     122      <code>class</code> attribute for the "Select" button part. This allows you to
     123      apply different styles to the button. If the button is disabled "_disabled" is
     124      appended to the class name.
     125    </td>
     126  </tr>
     127  <tr>
     128    <td>buttonstyle</td>
     129    <td>-</td>
     130    <td>no</td>
     131    <td>
     132      The value if this attribute goes directly into the standard HTML
     133      <code>style</code> attribute for the "Select" button part. This allows you to
     134      apply different styles to the button.
     135    </td>
     136  </tr>
     137  <tr>
     138    <td>buttontitle</td>
     139    <td>Select</td>
     140    <td>no</td>
     141    <td>
     142      The text on the "Select" button.
     143    </td>
     144  </tr>
     145  <tr>
     146    <td>buttonicon</td>
     147    <td>select.png</td>
     148    <td>no</td>
     149    <td>
     150      The icon to use on the "Select" button.
     151    </td>
     152  </tr>
     153  <tr>
    113154    <td>required</td>
    114155    <td>false</td>
     
    242283  private String style = null;
    243284
     285  private String buttonclass = "buttonclass";
     286  private String buttonstyle = null;
     287  private String buttontitle = "Select&hellip;";
     288  private String buttonicon = "select.png";
     289 
    244290  /**
    245291    If a value is required or not.
     
    331377    return style;
    332378  }
     379  /**
     380    @since 3.0
     381  */
     382  public void setButtonclass(String clazz)
     383  {
     384    this.buttonclass = clazz;
     385  }
     386  /**
     387    @since 3.0
     388  */
     389  public String getButtonclass()
     390  {
     391    return buttonclass;
     392  }
     393  /**
     394    @since 3.0
     395  */
     396  public void setButtonstyle(String style)
     397  {
     398    this.buttonstyle = style;
     399  }
     400  /**
     401    @since 3.0
     402  */
     403  public String getButtonstyle()
     404  {
     405    return buttonstyle;
     406  }
     407  /**
     408    @since 3.0
     409  */
     410  public void setButtontitle(String title)
     411  {
     412    this.buttontitle = title;
     413  }
     414  /**
     415    @since 3.0
     416  */
     417  public String getButtontitle()
     418  {
     419    return buttontitle;
     420  }
     421  /**
     422    @since 3.0
     423  */
     424  public void setButtonicon(String icon)
     425  {
     426    this.buttonicon = icon;
     427  }
     428  /**
     429    @since 3.0
     430  */
     431  public String getButtonicon()
     432  {
     433    return buttonicon;
     434  }
    333435 
    334436  public void setRequired(boolean required)
     
    454556  {
    455557    if (!isVisible()) return SKIP_BODY;
    456 //    Page page = (Page)findAncestorWithClass(this, Page.class);
     558    Page page = (Page)findAncestorWithClass(this, Page.class);
    457559
    458560    tryGetDirectoryPath = true;
     
    536638    {
    537639      sb.append("<td>");
    538       sb.append("<div class=\"buttonclass").append(disabled ? "_disabled": "").append("\"");
     640      sb.append("<div class=\"").append(getButtonclass()).append(disabled ? "_disabled": "").append("\"");
    539641      if (!disabled)
    540642      {
    541         sb.append(" onmouseover=\"this.className='buttonclass_hover';\" onmouseout=\"this.className='buttonclass';\"");
     643        //sb.append(" onmouseover=\"this.className='buttonclass_hover';\" onmouseout=\"this.className='buttonclass';\"");
    542644        sb.append(" onclick=\"").append(getOnselect()).append("\"");
    543645      }
    544       sb.append("><div class=\"buttonclass_inner\">Select&hellip;</div></div>");
     646      if (getButtonstyle() != null)
     647      {
     648        sb.append("style=\"").append(getButtonstyle()).append("\"");
     649      }
     650      sb.append("><div class=\"").append(getButtonclass()).append("_inner\">");
     651      String buttonImg = getButtonicon();
     652      if (buttonImg != null)
     653      {
     654        if (!buttonImg.startsWith("/"))
     655        {
     656          buttonImg = page.getRoot() + "images/" + buttonImg;
     657        }
     658        sb.append("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\"><tr><td style=\"width: 20px;\">");
     659        sb.append("<img src=\"").append(buttonImg).append("\" border=\"0\"></td><td style=\"text-align: left;\">");
     660      }
     661      sb.append(getButtontitle());
     662      if (buttonImg != null)
     663      {
     664        sb.append("</td></tr></table>");
     665      }
     666      sb.append("</div></div>");
    545667      sb.append("</td>\n");
    546668    }
  • trunk/src/core/common-queries.xml

    r5652 r5663  
    10911091      FROM BioMaterialEventData bme
    10921092      JOIN bme.sources src
    1093       WHERE index(src) = :bioMaterial
     1093      WHERE src.bioMaterial = :bioMaterial
    10941094    </sql>
    10951095    <description>
  • trunk/src/core/net/sf/basedb/core/BioMaterial.java

    r5643 r5663  
    2626import net.sf.basedb.core.Transactional.Action;
    2727import net.sf.basedb.core.data.BioMaterialData;
     28import net.sf.basedb.core.query.Hql;
     29import net.sf.basedb.core.query.Restrictions;
    2830
    2931/**
     
    167169  */
    168170  public abstract long countChildren(boolean pooled);
     171
     172  /**
     173    Get a query returning all events where this biomaterial has been used
     174    as a source item.
     175    @return A special query
     176    @since 3.0
     177  */
     178  public SpecialQuery<BioMaterialEventSource> getChildCreationEvents()
     179  {
     180    SpecialQuery<BioMaterialEventSource> query =
     181      new SpecialQuery<BioMaterialEventSource>(null, "BioMaterialEventSourceData", "es",
     182          new BioMaterialEventSource.BioMaterialEventSourceTransformer());
     183    query.restrictPermanent(Restrictions.eq(Hql.property("es", "bioMaterial"), Hql.entity(this)));
     184    return query;
     185  }
    169186 
    170187}
  • trunk/src/core/net/sf/basedb/core/BioMaterialEvent.java

    r5662 r5663  
    331331 
    332332    DbControl dc = getDbControl();
    333     Subtypable parent = null;
    334     ItemSubtype protocolSubtype = null;
    335     ItemSubtype hardwareSubtype = null;
     333    Subtypable createdItem = null;
    336334    String defaultProtocolId = null;
    337335    if (getEventType() == Type.BIOASSAY)
    338336    {
    339       parent = getPhysicalBioAssay();
     337      createdItem = getPhysicalBioAssay();
    340338    }
    341339    else
    342340    {
    343341      MeasuredBioMaterial bioMaterial = getBioMaterial();
    344       parent = bioMaterial;
    345       Item parentType = parent.getType();
    346       if (bioMaterial.isPooled())
    347       {
    348         defaultProtocolId = Protocol.POOLING;
    349       }
    350       else if (parentType == Item.SAMPLE)
     342      createdItem = bioMaterial;
     343      Item parentType = createdItem.getType();
     344      if (parentType == Item.SAMPLE)
    351345      {
    352346        defaultProtocolId = Protocol.SAMPLING;
     
    357351      }
    358352    }
    359     protocolSubtype = ItemSubtype.getRelatedSubtype(dc, parent, Item.PROTOCOL, SystemItems.getId(defaultProtocolId));
    360     hardwareSubtype = ItemSubtype.getRelatedSubtype(dc, parent, Item.HARDWARE, 0);
    361    
    362     if (!protocolHasBeenSet && protocolSubtype != null)
    363     {
    364       ProtocolData protocol =
    365         (ProtocolData)activeProject.findDefaultData(Item.PROTOCOL, protocolSubtype.getData(), false);
    366       if (protocol != null) getData().setProtocol(protocol);
    367       protocolHasBeenSet = true;
    368     }
    369     if (!hardwareHasBeenSet && hardwareSubtype != null)
     353   
     354    if (!protocolHasBeenSet)
     355    {
     356      ItemSubtype protocolSubtype =
     357        ItemSubtype.getRelatedSubtype(dc, createdItem, Item.PROTOCOL, SystemItems.getId(defaultProtocolId));
     358      if (protocolSubtype != null)
     359      {
     360        ProtocolData protocol =
     361          (ProtocolData)activeProject.findDefaultData(Item.PROTOCOL, protocolSubtype.getData(), false);
     362        if (protocol != null)
     363        {
     364          getData().setProtocol(protocol);
     365          protocolHasBeenSet = true;
     366        }
     367      }
     368    }
     369    if (!hardwareHasBeenSet)
    370370    {
    371371      HardwareData hardware =
    372         (HardwareData)activeProject.findDefaultData(Item.HARDWARE, hardwareSubtype.getData(), false);
    373       if (hardware != null) getData().setHardware(hardware);
    374       hardwareHasBeenSet = true;
     372        (HardwareData)activeProject.findDefaultRelatedData(dc, createdItem, Item.HARDWARE, false);
     373      if (hardware != null)
     374      {
     375        getData().setHardware(hardware);
     376        hardwareHasBeenSet = true;
     377      }
    375378    }
    376379  }
     
    618621 
    619622  /**
    620     Add a biomaterial as a source to this event. If the given biomaterial
    621     already is a source, the existing information is returned.
    622    
    623     @param bioMaterial The biomaterial
     623    Set a single parent item for this event. Any sources
     624    that are currently associated with it are removed and
     625    the used quantity is returned.
     626   
     627    @param parent The parent biomaterial, or null to remove all parents
     628    @since 3.0
     629  */
     630  public BioMaterialEventSource setSource(BioMaterial parent)
     631  {
     632    checkPermission(Permission.RESTRICTED_WRITE);
     633    if (parent != null)
     634    {
     635      parent.checkPermission(Permission.USE);
     636      checkAllowedSource(parent, false);
     637    }
     638    clearSources();
     639    BioMaterialEventSource eventSource = null;
     640    if (parent != null)
     641    {
     642      eventSource = addCheckedSource(parent);
     643    }
     644    return eventSource;
     645  }
     646
     647  /**
     648    Add a biomaterial as a source to this event. If the given
     649    biomaterial already is a source, the existing information is
     650    returned. If this event already has sources the new source
     651    must be of the same type as the existing sources and the
     652    produced biomaterial.
     653   
     654    @param bioMaterial The biomaterial (null is not allowed)
    624655    @return A BioMaterialEventSource object
     656    @since 3.0
    625657  */
    626658  public BioMaterialEventSource addSource(BioMaterial bioMaterial)
     
    629661    if (bioMaterial == null) throw new InvalidUseOfNullException("bioMaterial");
    630662    bioMaterial.checkPermission(Permission.USE);
    631     checkAllowedSource(bioMaterial);
     663   
     664    checkAllowedSource(bioMaterial, true);
    632665    return addCheckedSource(bioMaterial);
    633666  }
     
    636669  {
    637670    BioMaterialData bmData = (BioMaterialData)bioMaterial.getData();
    638     BioMaterialEventSourceData src = getData().getSources().get(bmData);
     671   
     672    Map<BioMaterialData, BioMaterialEventSourceData> sources = getData().getSources();
     673   
     674    BioMaterialEventSourceData src = sources.get(bmData);
    639675    if (src == null)
    640676    {
     
    642678      src.setBioMaterial(bmData);
    643679      src.setEvent(this.getData());
    644       getData().getSources().put(bmData, src);
    645     }
     680      sources.put(bmData, src);
     681    }
     682
     683    if (getData().getBioMaterial() != null)
     684    {
     685      // If the product is a biomaterial we may need to set parent + parent type
     686      MeasuredBioMaterialData product = getData().getBioMaterial();
     687      if (sources.size() == 1)
     688      {
     689        // This is the first parent
     690        product.setParentType(bioMaterial.getType().getValue());
     691        product.setParent(bmData);
     692      }
     693      else
     694      {
     695        // Clear if we get more than one parent
     696        product.setParent(null);
     697      }
     698    }
     699
    646700    return new BioMaterialEventSource(getDbControl(), src);
    647701  }
     
    657711      biomaterial is of another type
    658712    @throws BaseException If there is another error
     713    @since 3.0
    659714  */
    660715  public void removeSource(BioMaterial bioMaterial)
     
    663718    checkPermission(Permission.RESTRICTED_WRITE);
    664719    if (bioMaterial == null) throw new InvalidUseOfNullException("bioMaterial");
    665     checkAllowedSource(bioMaterial);
    666720    BioMaterialData data = (BioMaterialData)bioMaterial.getData();
    667     BioMaterialEventSourceData src = getData().getSources().remove(data);
     721    Map<BioMaterialData, BioMaterialEventSourceData> sources = getData().getSources();
     722    BioMaterialEventSourceData src = sources.remove(data);
     723   
     724    if (sources.size() == 0)
     725    {
     726      if (getData().getBioMaterial() != null)
     727      {
     728        getData().getBioMaterial().setParentType(null);
     729      }
     730    }
     731   
    668732    if (src == null) return;
    669733   
     
    680744
    681745  /**
    682     Check if the biomaterial is allowed as a source. It is allowed if:
    683     <ul>
    684     <li>This is a creation event
    685     <li>The created biomaterial is pooled
    686     <li>It is of the same type as the created biomaterial
    687     <li>It is not the same item as the created biomaterial
    688     </ul>
    689   */
    690   private void checkAllowedSource(BioMaterial bioMaterial)
     746    Check if the biomaterial is allowed as a source.
     747  */
     748  private void checkAllowedSource(BioMaterial source, boolean forAdd)
    691749    throws PermissionDeniedException, InvalidDataException, BaseException
    692750  {
    693751    Type eventType = getEventType();
     752    Item sourceType = source.getType();
    694753    switch (eventType)
    695754    {
     
    700759      case BIOASSAY:
    701760      {
    702         if (bioMaterial.getType() != Item.EXTRACT)
     761        if (sourceType != Item.EXTRACT)
    703762        {
    704763          throw new InvalidDataException("The source for a physical bioassay must be an extract");
     
    708767      case CREATION:
    709768      {
    710         MeasuredBioMaterial parent = getBioMaterial();
    711         if (!parent.isPooled())
     769        MeasuredBioMaterial product = getBioMaterial();
     770        Item productType = product.getType();
     771        Item parentType = product.getParentType();
     772       
     773        if (forAdd && parentType != null)
    712774        {
    713           throw new InvalidDataException("Non-pooled biomaterials can't have sources");
     775          if (parentType != sourceType)
     776          {
     777            throw new InvalidDataException("Can't add '" + source.getName() + "' (" + sourceType +
     778                ") as parent since there is already a " + parentType + " parent");
     779          }
    714780        }
    715         else if (bioMaterial.getType() != parent.getType())
     781       
     782        if (productType != sourceType)
    716783        {
    717           throw new InvalidDataException("The source biomaterial must be of the same type as the produced biomaterial");
     784          if (productType == Item.EXTRACT && sourceType != Item.SAMPLE)
     785          {
     786            throw new InvalidDataException("The parent for an extract must be an extract or sample: " + source);
     787          }
     788          if (productType == Item.SAMPLE && sourceType != Item.BIOSOURCE)
     789          {
     790            throw new InvalidDataException("The parent for a sample must be a biosource or sample: " + source);
     791          }
    718792        }
    719         else if (bioMaterial.equals(parent))
     793       
     794        if (source.equals(product))
    720795        {
    721           throw new InvalidDataException("The source biomaterial cannot be the same as the produced biomaterial");
     796          throw new InvalidDataException("The parent biomaterial cannot be the same as the produced biomaterial: " + source);
    722797        }
    723798        break;
     
    731806
    732807  /**
    733     Set a single source. This method is used for non-pooled biomaterial
    734     to specify the parent.
    735     @see Extract#setSample(Sample)
    736   */
    737   BioMaterialEventSource setSource(MeasuredBioMaterial bioMaterial)
    738     throws PermissionDeniedException, InvalidDataException
    739   {
    740     clearSources();
    741     return bioMaterial == null ? null : addCheckedSource(bioMaterial);
    742   }
    743  
    744   /**
    745808    Clear the sources collection and return the used quantities to
    746809    the source biomaterials.
    747   */
    748   void clearSources()
     810    @since 3.0
     811  */
     812  public void clearSources()
    749813  {
    750814    DbControl dc = getDbControl();
    751     for (BioMaterialEventSourceData src : getData().getSources().values())
     815    Map<BioMaterialData, BioMaterialEventSourceData> sources = getData().getSources();
     816    for (BioMaterialEventSourceData src : sources.values())
    752817    {
    753818      BioMaterialData bioMaterial = src.getBioMaterial();
     
    759824      dc.getHibernateSession().delete(src);
    760825    }
    761     getData().getSources().clear();
     826    sources.clear();
     827    if (getData().getBioMaterial() != null)
     828    {
     829      getData().getBioMaterial().setParentType(null);
     830      getData().getBioMaterial().setParent(null);
     831    }
    762832  }
    763833
     
    780850    @return An {@link ItemQuery} object
    781851  */
    782   public ItemQuery<? extends MeasuredBioMaterial> getSources()
    783   {
    784     ItemQuery<? extends MeasuredBioMaterial> query = null;
     852  public ItemQuery<? extends BioMaterial> getSources()
     853  {
     854    ItemQuery<? extends BioMaterial> query = null;
    785855    MeasuredBioMaterialData bioMaterialData = getData().getBioMaterial();
    786     boolean pooled = bioMaterialData != null ? bioMaterialData.isPooled() : false;
    787     Item parentType = Item.fromDataObject(bioMaterialData == null ? getData().getPhysicalBioAssay() : bioMaterialData);
     856    Item parentType = null;
     857    if (getEventType() == Type.BIOASSAY)
     858    {
     859      parentType = Item.EXTRACT;
     860    }
     861    else
     862    {
     863      Integer tmp = getData().getBioMaterial().getParentType();
     864      parentType = tmp != null ? Item.fromValue(tmp) : Item.fromDataObject(getData().getBioMaterial());
     865    }
    788866    switch (parentType)
    789867    {
     868      case EXTRACT:
     869      {
     870        query = Extract.getQuery();
     871        break;
     872      }
    790873      case SAMPLE:
    791874      {
     
    793876        break;
    794877      }
    795       case EXTRACT:
    796       {
    797         if (pooled)
    798         {
    799           query = Extract.getQuery();
    800         }
    801         else
    802         {
    803           query = Sample.getQuery();
    804         }
    805         break;
    806       }
    807       case PHYSICALBIOASSAY:
    808       {
    809         query = Extract.getQuery();
     878      case BIOSOURCE:
     879      {
     880        query = BioSource.getQuery();
    810881        break;
    811882      }
  • trunk/src/core/net/sf/basedb/core/BioSource.java

    r5357 r5663  
    185185  {
    186186    Sample s= Sample.getNew(getDbControl());
    187     s.setBioSource(this);
     187    s.getCreationEvent().setSource(this);
    188188    return s;
    189189  }
  • trunk/src/core/net/sf/basedb/core/Extract.java

    r5662 r5663  
    2828
    2929import java.util.Set;
    30 import java.util.HashSet;
    3130
    3231/**
     
    143142  {
    144143    return TYPE;
    145   }
    146   // -------------------------------------------
    147   /*
    148     From the Annotatable interface
    149     -------------------------------------------
    150   */
    151   /**
    152     Get the sample or pooled extracts.
    153   */
    154   public Set<Annotatable> getAnnotatableParents()
    155     throws BaseException
    156   {
    157     Set<Annotatable> annotatable = new HashSet<Annotatable>();
    158     try
    159     {
    160       if (isPooled())
    161       {
    162         ItemQuery<? extends MeasuredBioMaterial> query = getCreationEvent().getSources();
    163         query.include(Include.ALL);
    164         annotatable.addAll(query.list(getDbControl()));
    165       }
    166       else if (getData().getParent() != null)
    167       {
    168         annotatable.add(getSample());
    169       }
    170     }
    171     catch (PermissionDeniedException ex)
    172     {}
    173     return annotatable;
    174144  }
    175145  // -------------------------------------------
     
    228198  // -------------------------------------------
    229199
     200  /**
     201    Get the tag that has been applied to this extract in order
     202    to be able to distinguish it from other extracts on a
     203    physical bioassay.
     204    @return A tag or null if the extract is not tagged
     205    @since 3.0
     206  */
    230207  public Tag getTag()
    231208  {
     
    233210  }
    234211 
     212  /**
     213    Set the tag that was applied to this extract in order
     214    to be able to distinguish it from other extracts on a
     215    physical bioassay.
     216    @param tag The tag, or null if the extract is not tagged
     217    @since 3.0
     218  */
    235219  public void setTag(Tag tag)
    236220  {
     
    239223    getData().setTag(tag == null ? null : tag.getData());
    240224  }
    241  
    242   /**
    243     Get the {@link Sample} that is the parent of this extract.
    244     @return A <code>Sample</code> object or null if this is a pooled or
    245       standalone extract
    246     @throws PermissionDeniedException If the logged in user doesn't have read
    247       permission for the sample
    248     @throws BaseException If there is another error
    249   */
    250   public Sample getSample()
    251     throws PermissionDeniedException, BaseException
    252   {
    253     return getDbControl().getItem(Sample.class, getData().getParent());
    254   }
    255 
    256   /**
    257     Set the {@link Sample} item that is the parent
    258     of this extract.
    259     @param sample The new <code>Sample</code> item
    260     @throws PermissionDeniedException If the logged in user doesn't have
    261       write permission for this extract or use permission for the sample
    262     @throws InvalidDataException If this is a pooled extract
    263     @throws BaseException If there is another error
    264     @since 3.0
    265   */
    266   public BioMaterialEventSource setSample(Sample sample)
    267     throws PermissionDeniedException, InvalidDataException, BaseException
    268   {
    269     checkPermission(Permission.WRITE);
    270     if (sample != null) sample.checkPermission(Permission.USE);
    271     if (isPooled())
    272     {
    273       throw new InvalidDataException("A pooled extract can't have a parent sample");
    274     }
    275     getData().setParent(sample == null ? null : sample.getData());
    276     return getCreationEvent().setSource(sample);
    277   }
    278  
    279 
    280   public BioMaterialEventSource setExtract(Extract extract)
    281     throws PermissionDeniedException, InvalidDataException, BaseException
    282   {
    283     checkPermission(Permission.WRITE);
    284     if (extract != null) extract.checkPermission(Permission.USE);
    285    
    286     getData().setPooled(true);
    287     getData().setParent(extract == null ? null : extract.getData());
    288     return getCreationEvent().setSource(extract);
    289   }
    290 
    291225 
    292226  /**
     
    322256      FROM BioMaterialEventData bme
    323257      JOIN bme.sources src
    324       WHERE index(src) = :bioMaterial
     258      WHERE src.bioMaterial = :bioMaterial
    325259    */
    326260    query.setEntity("bioMaterial", this.getData());
     
    330264  /**
    331265    Count the number of child extracts. Since an extract
    332     can't have non-pooled children, this method always return
    333     0 if pooled = false.
     266    can only have other extracts as children, this method always return
     267    0 if extractsOnly = false.
    334268    @since 2.16
    335269  */
    336270  @Override
    337   public long countChildren(boolean pooled)
    338   {
    339     return pooled ? countExtracts() : 0;
     271  public long countChildren(boolean extractsOnly)
     272  {
     273    return extractsOnly ? countExtracts() : 0;
    340274  }
    341275
  • trunk/src/core/net/sf/basedb/core/MeasuredBioMaterial.java

    r5643 r5663  
    2525
    2626import java.util.Date;
     27import java.util.HashSet;
    2728import java.util.Set;
    2829
     
    3132import net.sf.basedb.core.data.BioWellData;
    3233import net.sf.basedb.core.data.MeasuredBioMaterialData;
    33 import net.sf.basedb.core.query.Expressions;
    34 import net.sf.basedb.core.query.Hql;
    35 import net.sf.basedb.core.query.Restrictions;
    3634import net.sf.basedb.util.EqualsHelper;
    3735
     
    8785      FROM BioMaterialEventData bme
    8886      JOIN bme.sources src
    89       WHERE index(src) = :bioMaterial
     87      WHERE src.bioMaterial = :bioMaterial
    9088    */
    9189    query.setEntity("bioMaterial", this.getData());
     
    110108        FROM BioMaterialEventData bme
    111109        JOIN bme.sources src
    112         WHERE index(src) = :bioMaterial
     110        WHERE src.bioMaterial = :bioMaterial
    113111      */
    114112    query.setEntity("bioMaterial", this.getData());
     
    173171  // -------------------------------------------
    174172  /*
     173    From the Annotatable interface
     174    -------------------------------------------
     175  */
     176  /**
     177    Get the biosource or pooled samples.
     178  */
     179  public Set<Annotatable> getAnnotatableParents()
     180    throws BaseException
     181  {
     182    Set<Annotatable> annotatable = new HashSet<Annotatable>();
     183    try
     184    {
     185      if (getData().getParent() != null)
     186      {
     187        annotatable.add(getParent());
     188      }
     189      else if (getParentType() != null)
     190      {
     191        ItemQuery<? extends BioMaterial> query = getCreationEvent().getSources();
     192        query.include(Include.ALL);
     193        annotatable.addAll(query.list(getDbControl()));
     194      }
     195    }
     196    catch (PermissionDeniedException ex)
     197    {}
     198    return annotatable;
     199  }
     200  // -------------------------------------------
     201
     202 
     203  /*
    175204    From the Subtypable interface
    176205    -----------------------------
     
    290319 
    291320  /**
    292     Check if this biomaterial was created by pooling or not.
    293     @return TRUE if pooled, FALSE otherwise.
    294   */
    295   public boolean isPooled()
    296   {
    297     return getData().isPooled();
    298   }
    299  
    300   /**
    301     Specify if this biomaterial was created by pooling or not. Changing this property
    302     also clears the parent biomaterial and the sources collection for the creation event.
    303     @param pooled set to TRUE if pooled, FALSE otherwise.
    304     @throws PermissionDeniedException If the logged in user doesn't have
    305       write permission
    306     @throws BaseException If there is another error
    307     @see BioMaterialEvent#getSources()
    308   */
    309   public void setPooled(boolean pooled)
    310     throws PermissionDeniedException, BaseException
    311   {
    312     checkPermission(Permission.WRITE);
    313     boolean current = getData().isPooled();
    314     if (current != pooled)
    315     {
    316       getCreationEvent().clearSources();
    317       getData().setParent(null);
    318       getData().setPooled(pooled);
    319     }
     321    Get the item type of the parent biomaterial. The parent type
     322    must be either the same type as the current biomaterial or "one
     323    step up" in the Extract -- Sample -- BioSource chain.
     324    @return The parent type, or null if the biomaterial doesn't have any parents
     325    @since 3.0
     326  */
     327  public Item getParentType()
     328  {
     329    Integer parentType = getData().getParentType();
     330    return parentType == null ? null : Item.fromValue(parentType);
     331  }
     332
     333  /**
     334    Get the parent biomaterial if there is a single parent item only.
     335    @return The parent biomaterial or null if there is not exactly one
     336      parent
     337    @since 3.0
     338    @see #hasSingleParent()
     339   */
     340  public BioMaterial getParent()
     341  {
     342    return getDbControl().getItem(BioMaterial.class, getData().getParent());
     343  }
     344 
     345  /**
     346    Checks if this biomaterial has a single parent item or not.
     347    @return TRUE if there is exactly one parent, FALSE if there are
     348      0 or 2 or more parents
     349    @since 3.0
     350    @see #getParentType()
     351  */
     352  public boolean hasSingleParent()
     353  {
     354    return getData().getParent() != null;
    320355  }
    321356 
     
    355390  {
    356391    return BioMaterialEvent.getQuery(this);
    357   }
    358  
    359   /**
    360     Get a query that returns all events where this biomaterial
    361     has been used as a source.
    362       @return An {@link ItemQuery} object
    363       @since 2.9
    364    */
    365   public ItemQuery<BioMaterialEvent> getPoolingEvents()
    366   {
    367     ItemQuery<BioMaterialEvent> query = new ItemQuery<BioMaterialEvent>(BioMaterialEvent.class, null);
    368     query.setDistinct(true);  // Otherwise, the join to sources can result in one copy for each source
    369     query.joinPermanent(Hql.leftJoin("sources", "src"));
    370     query.joinPermanent(Hql.leftJoin("bioMaterial", "bm"));
    371     query.restrictPermanent(
    372       Restrictions.and(
    373         Restrictions.eq(
    374           Hql.index("src", null),
    375           Hql.entity(this)
    376         ),
    377         Restrictions.eq(
    378           Hql.property("bm", "pooled"),
    379           Expressions.parameter("isPooled", true, Type.BOOLEAN)
    380         ),
    381         Restrictions.eq(
    382           Hql.property("eventType"),
    383           Expressions.integer(BioMaterialEvent.Type.CREATION.getValue())
    384         )
    385       )
    386     );
    387     return query;   
    388392  }
    389393 
  • trunk/src/core/net/sf/basedb/core/Sample.java

    r5662 r5663  
    2828
    2929import java.util.Set;
    30 import java.util.HashSet;
    3130
    3231/**
     
    130129  {
    131130    return TYPE;
    132   }
    133   // -------------------------------------------
    134   /*
    135     From the Annotatable interface
    136     -------------------------------------------
    137   */
    138   /**
    139     Get the biosource or pooled samples.
    140   */
    141   public Set<Annotatable> getAnnotatableParents()
    142     throws BaseException
    143   {
    144     Set<Annotatable> annotatable = new HashSet<Annotatable>();
    145     try
    146     {
    147       if (isPooled())
    148       {
    149         ItemQuery<? extends MeasuredBioMaterial> query = getCreationEvent().getSources();
    150         query.include(Include.ALL);
    151         annotatable.addAll(query.list(getDbControl()));
    152       }
    153       else if (getData().getParent() != null)
    154       {
    155         annotatable.add(getBioSource());
    156       }
    157     }
    158     catch (PermissionDeniedException ex)
    159     {}
    160     return annotatable;
    161131  }
    162132  // -------------------------------------------
     
    216186
    217187  /**
    218     Get the {@link BioSource} that is the parent of this sample.
    219     @return A <code>BioSource</code> object or null if this is a pooled or
    220       standalone sample
    221     @throws PermissionDeniedException If the logged in user doesn't have read
    222       permission for the biosource
    223     @throws BaseException If there is another error
    224   */
    225   public BioSource getBioSource()
    226     throws PermissionDeniedException, BaseException
    227   {
    228     return getDbControl().getItem(BioSource.class, getData().getParent());
    229   }
    230  
    231   /**
    232     Set the {@link BioSource} item that is the parent
    233     of this sample.
    234     @param bioSource The parent <code>BioSource</code> item
    235     @throws PermissionDeniedException If the logged in user doesn't have
    236       write permission for this sample or use permission for the biosource
    237     @throws InvalidDataException If this is a pooled sample
    238     @throws BaseException If there is another error
    239   */
    240   public void setBioSource(BioSource bioSource)
    241     throws PermissionDeniedException, InvalidDataException
    242   {
    243     checkPermission(Permission.WRITE);
    244     if (bioSource != null) bioSource.checkPermission(Permission.USE);
    245     if (isPooled())
    246     {
    247       throw new InvalidDataException("A pooled sample can't have a parent biosource");
    248     }
    249     getData().setParent(bioSource == null ? null : bioSource.getData());
    250   }
    251  
    252   /**
    253188    Create a new {@link Extract} from this sample.
    254189    @param usedQuantity The quantity used from this sample or null
     
    281216  {
    282217    Extract e = Extract.getNew(getDbControl(), master);
    283     e.setSample(this).setUsedQuantity(usedQuantity);
     218    e.getCreationEvent().setSource(e).setUsedQuantity(usedQuantity);
    284219    return e;
    285220  }
     
    366301  /**
    367302    Count the number of child samples or extracts.
    368     @param pooled TRUE = count child samples, FALSE = count child extracts
     303    @param samples TRUE = count child samples, FALSE = count child extracts
    369304    @since 2.16
    370305  */
    371306  @Override
    372   public long countChildren(boolean pooled)
    373   {
    374     return pooled ? countSamples() : countExtracts();
     307  public long countChildren(boolean samples)
     308  {
     309    return samples ? countSamples() : countExtracts();
    375310  }
    376311
  • trunk/src/core/net/sf/basedb/core/data/MeasuredBioMaterialData.java

    r5662 r5663  
    4545  private BioMaterialData parent;
    4646  /**
    47     Get the parent biomaterial. Used for non-pooled biomaterials. The
    48     core must add logic to check that only a biomaterial of the parent
    49     type is linked.
     47    Get the parent biomaterial. Used when a biomaterial has a single parent item.
    5048    @hibernate.many-to-one column="`parent_id`" not-null="false" outer-join="false"
    5149  */
     
    8785  }
    8886 
    89   private boolean pooled;
     87  private Integer parentType;
    9088  /**
    91     If the biomaterial was created by pooling other biomaterials of the same type
    92     or not.
    93     @hibernate.property column="`pooled`" type="boolean" not-null="false"
     89    Get the type of the parent item. Null if the biomaterial doesn't have any parents.
     90    @hibernate.property column="`parent_type`" type="int" not-null="false"
     91    @since 3.0
    9492  */
    95   public boolean isPooled()
     93  public Integer getParentType()
    9694  {
    97     return pooled;
     95    return parentType;
    9896  }
    99   public void setPooled(boolean pooled)
     97  public void setParentType(Integer parentType)
    10098  {
    101     this.pooled = pooled;
     99    this.parentType = parentType;
    102100  }
     101
    103102  private BioMaterialEventData creationEvent;
    104103  /**
  • trunk/src/core/net/sf/basedb/util/biomaterial/ChildrenTransformer.java

    r5662 r5663  
    4040/**
    4141  Collection transformer that given a collection of biomaterials
    42   finds all pooled children (of the same type).
     42  finds all children of the same type.
    4343
    4444  @author Nicklas
    45   @version 2.10
     45  @since 3.0
    4646  @base.modified $Date$
    4747*/
    48 public class PooledChildrenTransformer<I extends MeasuredBioMaterial>
     48public class ChildrenTransformer<I extends MeasuredBioMaterial>
    4949  implements CollectionTransformer<I, I>
    5050{
     
    5454  private final boolean copySources;
    5555 
    56   public PooledChildrenTransformer(DbControl dc, boolean copySources, ItemQuery<I> query)
     56  public ChildrenTransformer(DbControl dc, boolean copySources, ItemQuery<I> query)
    5757  {
    5858    this.dc = dc;
  • trunk/src/core/net/sf/basedb/util/biomaterial/ExtractToSampleTransformer.java

    r4723 r5663  
    4646  parents to the extract. If you want to follow pooled extracts up
    4747  to samples, you should combine this transformer
    48   and a {@link PooledParentsTransformer} with the help of a
     48  and a {@link ParentsTransformer} with the help of a
    4949  {@link MultiStepCollectionTransformer}.
    5050
  • trunk/src/core/net/sf/basedb/util/biomaterial/ListUtil.java

    r5641 r5663  
    132132    @param sourceItem The type of source items
    133133    @param destinationItem The type of destination items
    134     @param pooled If pooled children/parents should be considered or not
     134    @param sameType If children/parents of the same type should be considered or not
    135135    @return A collection transformer (never null)
    136136  */
    137137  @SuppressWarnings("unchecked")
    138   public static CollectionTransformer createTransformer(DbControl dc, Item sourceItem, Item destinationItem, boolean pooled)
     138  public static CollectionTransformer createTransformer(DbControl dc, Item sourceItem, Item destinationItem, boolean sameType)
    139139  {
    140140    // The allowed item types
     
    167167        {
    168168          // Moving down
    169           if (pooled) transformers.add(new PooledChildrenTransformer<Sample>(dc, true, Sample.getQuery()));
     169          if (sameType) transformers.add(new ChildrenTransformer<Sample>(dc, true, Sample.getQuery()));
    170170          transformers.add(new SampleToExtractTransformer(dc));
    171171        }
     
    173173        {
    174174          // Moving up
    175           if (pooled) transformers.add(new PooledParentsTransformer<Sample>(dc, true, Sample.getQuery()));
     175          if (sameType) transformers.add(new ParentsTransformer<Sample>(dc, true, Sample.getQuery()));
    176176          transformers.add(new SampleToBioSourceTransformer(dc));
    177177        }
     
    182182        {
    183183          // Moving down
    184           if (pooled) transformers.add(new PooledChildrenTransformer<Extract>(dc, true, Extract.getQuery()));
     184          if (sameType) transformers.add(new ChildrenTransformer<Extract>(dc, true, Extract.getQuery()));
    185185        }
    186186        else
    187187        {
    188188          // Moving up
    189           if (pooled) transformers.add(new PooledParentsTransformer<Extract>(dc, true, Extract.getQuery()));
     189          if (sameType) transformers.add(new ParentsTransformer<Extract>(dc, true, Extract.getQuery()));
    190190          transformers.add(new ExtractToSampleTransformer(dc));
    191191        }
     
    201201    }
    202202   
    203     if (pooled && destinationItem != Item.BIOSOURCE)
     203    if (sameType && destinationItem != Item.BIOSOURCE)
    204204    {
    205205      if (step == 1)
    206206      {
    207207        // Moving down
    208         transformers.add(new PooledChildrenTransformer(dc, true, getQuery(destinationItem)));
     208        transformers.add(new ChildrenTransformer(dc, true, getQuery(destinationItem)));
    209209      }
    210210      else
    211211      {
    212212        // Moving up
    213         transformers.add(new PooledParentsTransformer(dc, true, getQuery(destinationItem)));
     213        transformers.add(new ParentsTransformer(dc, true, getQuery(destinationItem)));
    214214      }
    215215    }
  • trunk/src/core/net/sf/basedb/util/biomaterial/ParentsTransformer.java

    r5662 r5663  
    3939
    4040/**
    41   Collection transformer that given a collection of (pooled)
    42   biomaterials finds all parents (of the same type).
     41  Collection transformer that given a collection of
     42  biomaterials finds all parents of the same type
    4343
    4444  @author Nicklas
    45   @version 2.10
     45  @since 3.0
    4646  @base.modified $Date$
    4747*/
    48 public class PooledParentsTransformer<I extends MeasuredBioMaterial>
     48public class ParentsTransformer<I extends MeasuredBioMaterial>
    4949  implements CollectionTransformer<I, I>
    5050{
     
    5454  private final boolean copySources;
    5555 
    56   public PooledParentsTransformer(DbControl dc, boolean copySources, ItemQuery<I> query)
     56  public ParentsTransformer(DbControl dc, boolean copySources, ItemQuery<I> query)
    5757  {
    5858    this.dc = dc;
  • trunk/src/core/net/sf/basedb/util/biomaterial/SampleToBioSourceTransformer.java

    r4723 r5663  
    4646  parents to the samples. If you want to follow pooled samples up
    4747  to biosources, you should combine this transformer
    48   and a {@link PooledParentsTransformer} with the help of a
     48  and a {@link ParentsTransformer} with the help of a
    4949  {@link MultiStepCollectionTransformer}.
    5050
  • trunk/src/core/net/sf/basedb/util/biomaterial/SampleToExtractTransformer.java

    r4723 r5663  
    4545  children to the samples. If you want to include extracts that are
    4646  children to pooled samples, you should combine this transformer
    47   with a {@link PooledChildrenTransformer} with the help of a
     47  with a {@link ChildrenTransformer} with the help of a
    4848  {@link MultiStepCollectionTransformer}.
    4949
  • trunk/src/core/net/sf/basedb/util/overview/loader/BioSourceLoader.java

    r5500 r5663  
    6868    {
    6969      Sample sample = (Sample)sampleNode.getItem(dc);
    70       bioSource = sample.getBioSource();
     70      bioSource = (BioSource)sample.getParent();
    7171    }
    7272    catch (PermissionDeniedException ex)
  • trunk/src/core/net/sf/basedb/util/overview/loader/ExtractLoader.java

    r5657 r5663  
    3030import net.sf.basedb.core.ItemQuery;
    3131import net.sf.basedb.core.ItemResultIterator;
    32 import net.sf.basedb.core.RawBioAssay;
    3332import net.sf.basedb.core.Sample;
    3433import net.sf.basedb.util.overview.Fix;
     
    106105    else if (parentItem == Item.EXTRACT)
    107106    {
    108       returnNode = createReverseNode((Extract)parentNode.getItem(dc), dc, context, parentNode);
     107      Extract e = (Extract)parentNode.getItem(dc);
     108      if (e.hasSingleParent())
     109      {
     110        createSingleParentReverseNode(e, dc, context, parentNode);
     111      }
     112      else
     113      {
     114        returnNode = createPooledReverseNode(e, dc, context, parentNode);
     115      }
    109116    }
    110117    else if (parentItem == Item.DERIVEDBIOASSAY)
     
    160167  {
    161168    Extract extract = (Extract)extractNode.getItem();
    162     if (extract.isPooled())
     169    if (extract.getParentType() == Item.EXTRACT)
    163170    {
    164171      getNodeLoader(context, Item.EXTRACT).createReverseNode(dc, context, extractNode);
     
    175182  */
    176183  @SuppressWarnings("unchecked")
    177   private Node createReverseNode(Extract product, DbControl dc, OverviewContext context, Node parentNode)
     184  private Node createPooledReverseNode(Extract product, DbControl dc, OverviewContext context, Node parentNode)
    178185  {
    179186    NodeFactory<Extract> nf = getNodeFactory(dc, context);
     
    212219
    213220  /**
     221    Create a reverse-loading extract node from an extract. Eg. the child node
     222    is the extract that is the parent of the (non-pooled) extract.
     223  */
     224  private Node createSingleParentReverseNode(Extract bioMaterial, DbControl dc, OverviewContext context, Node parentNode)
     225  {
     226    NodeFactory<Extract> nf = getNodeFactory(dc, context);
     227    Extract extract = null;
     228    boolean denied = false;
     229    try
     230    {
     231      extract = (Extract)bioMaterial.getParent();
     232    }
     233    catch (PermissionDeniedException ex)
     234    {
     235      denied = true;
     236    }
     237    Node sampleNode = createItemNode(nf, extract, extract, denied,
     238        parentNode, ChildNodeDirection.REVERSE);
     239    return sampleNode;
     240  }
     241
     242  /**
    214243    Create reverse-loading extract nodes from a physical bioassay. Eg. the child nodes
    215244    are the extracts that has been used on a bioassay.
  • trunk/src/core/net/sf/basedb/util/overview/loader/SampleLoader.java

    r5500 r5663  
    2121*/
    2222package net.sf.basedb.util.overview.loader;
     23
     24import java.util.Iterator;
    2325
    2426import net.sf.basedb.core.BioSource;
     
    2830import net.sf.basedb.core.ItemQuery;
    2931import net.sf.basedb.core.ItemResultIterator;
     32import net.sf.basedb.core.MeasuredBioMaterial;
    3033import net.sf.basedb.core.PermissionDeniedException;
    3134import net.sf.basedb.core.Sample;
     
    99102    if (parentType == Item.EXTRACT)
    100103    {
    101       returnNode = createReverseNode((Extract)parentNode.getItem(dc), dc, context, parentNode);
     104      returnNode = createSingleParentReverseNode((Extract)parentNode.getItem(dc), dc, context, parentNode);
    102105    }
    103106    else if (parentType == Item.SAMPLE)
    104107    {
    105       returnNode = createReverseNode((Sample)parentNode.getItem(dc), dc, context, parentNode);
     108      Sample s = (Sample)parentNode.getItem(dc);
     109      if (s.hasSingleParent())
     110      {
     111        createSingleParentReverseNode(s, dc, context, parentNode);
     112      }
     113      else
     114      {
     115        returnNode = createPooledReverseNode(s, dc, context, parentNode);
     116      }
    106117    }
    107118    return returnNode;
     
    150161  {
    151162    Sample sample = (Sample)sampleNode.getItem();
    152     if (sample.isPooled())
     163    if (sample.getParentType() == Item.SAMPLE)
    153164    {
    154165      getNodeLoader(context, Item.SAMPLE).createReverseNode(dc, context, sampleNode);
     
    162173 
    163174  /**
    164     Create reverse-loading samples nodes of a pooled sample. Eg. the child nodes
    165     are the source samples that was pooled to create the given product.
     175    Create reverse-loading samples nodes of a sample with other sample(s) as parent items.
     176    Eg. the child nodes are the source sample(s) that was used to create the given product.
    166177  */
    167178  @SuppressWarnings("unchecked")
    168   private Node createReverseNode(Sample product, DbControl dc, OverviewContext context, Node parentNode)
     179  private Node createPooledReverseNode(Sample product, DbControl dc, OverviewContext context, Node parentNode)
    169180  {
    170181    NodeFactory<Sample> nf = getNodeFactory(dc, context);
    171182    Node folderNode = null;
    172183    ItemQuery<Sample> query = (ItemQuery<Sample>)context.initQuery(product.getCreationEvent().getSources(), "name");
    173     ItemResultIterator<Sample> it = query.iterate(dc);
     184    Iterator<Sample> it = query.iterate(dc);
    174185    int numSamples = 0;
    175186    while (it.hasNext())
     
    202213
    203214  /**
    204     Create a reverse-loading sample node from an extract. Eg. the child node
    205     is the sample that is the parent of the (non-pooled) extract.
    206   */
    207   private Node createReverseNode(Extract extract, DbControl dc, OverviewContext context, Node parentNode)
     215    Create a reverse-loading sample node from an extract or sample. Eg. the child node
     216    is the sample that is the parent of the (non-pooled) extract/sample.
     217  */
     218  private Node createSingleParentReverseNode(MeasuredBioMaterial bioMaterial, DbControl dc, OverviewContext context, Node parentNode)
    208219  {
    209220    NodeFactory<Sample> nf = getNodeFactory(dc, context);
     
    212223    try
    213224    {
    214       sample = extract.getSample();
     225      sample = (Sample)bioMaterial.getParent();
    215226    }
    216227    catch (PermissionDeniedException ex)
  • trunk/src/plugins/core/net/sf/basedb/plugins/batchimport/ExtractImporter.java

    r5662 r5663  
    202202    if (pooledMapper != null)
    203203    {
    204       extract.setPooled(Values.getBoolean(pooledMapper.getValue(data)));
     204      //extract.setPooled(Values.getBoolean(pooledMapper.getValue(data)));
    205205    }
    206206
     
    216216    {
    217217      String nameOrId = protocolMapper.getValue(data);
    218       ItemSubtype type = ItemSubtype.getRelatedSubtype(dc, extract, Item.PROTOCOL,
    219           SystemItems.getId(extract.isPooled() ? Protocol.POOLING : Protocol.EXTRACTION));
     218      ItemSubtype type = ItemSubtype.getRelatedSubtype(dc, extract, Item.PROTOCOL, SystemItems.getId(Protocol.EXTRACTION));
    220219      Protocol protocol = findProtocol(dc, FallbackIdMethod.NAME_OR_EXTERNALID_OR_ID, nameOrId, type);
    221220      if (nameOrId == null || protocol != null) creationEvent.setProtocol(protocol);
     
    233232      }
    234233    }
     234    /*
    235235    if (!extract.isPooled())
    236236    {
     237    */
    237238      if (parentMapper != null)
    238239      {
     
    244245        if (nameOrId == null || sample != null)
    245246        {
    246           BioMaterialEventSource evtSrc = extract.setSample(sample);
     247          BioMaterialEventSource evtSrc = extract.getCreationEvent().setSource(sample);
    247248          if (evtSrc != null) evtSrc.setUsedQuantity(usedQuantity);
    248249        }
    249250      }
     251      /*
    250252    }
    251253    else
     
    253255      updateMultiLineItem(dc, extract, data, 0);
    254256    }
     257    */
    255258  }
    256259 
     
    262265    FlatFileParser.Data data, int multiLineNum)
    263266  {
    264     if (parentMapper != null && extract.isPooled())
     267    if (parentMapper != null) // && extract.isPooled())
    265268    {
    266269      String nameOrId = parentMapper.getValue(data);
  • trunk/src/plugins/core/net/sf/basedb/plugins/batchimport/LabeledExtractImporter.java

    r5662 r5663  
    206206    if (pooledMapper != null)
    207207    {
    208       extract.setPooled(Values.getBoolean(pooledMapper.getValue(data)));
     208      //extract.setPooled(Values.getBoolean(pooledMapper.getValue(data)));
    209209    }
    210210    if (protocolMapper != null)
    211211    {
    212212      String nameOrId = protocolMapper.getValue(data);
    213       ItemSubtype type = ItemSubtype.getById(dc,
    214           SystemItems.getId(extract.isPooled() ? Protocol.POOLING : Protocol.LABELING));
     213      ItemSubtype type = ItemSubtype.getById(dc, SystemItems.getId(Protocol.LABELING));
    215214      Protocol protocol = findProtocol(dc, FallbackIdMethod.NAME_OR_EXTERNALID_OR_ID, nameOrId, type);
    216215      if (nameOrId == null || protocol != null) creationEvent.setProtocol(protocol);
     
    237236      }
    238237    }
     238    /*
    239239    if (!extract.isPooled())
    240240    {
     241    */
    241242      if (parentMapper != null)
    242243      {
     
    247248        if (nameOrId == null || parent != null)
    248249        {
    249           BioMaterialEventSource evtSrc = extract.setExtract(parent);
     250          BioMaterialEventSource evtSrc = extract.getCreationEvent().setSource(parent);
    250251          if (evtSrc != null) evtSrc.setUsedQuantity(usedQuantity);
    251252        }
    252253      }
     254      /*
    253255    }
    254256    else
     
    256258      updateMultiLineItem(dc, extract, data, 0);
    257259    }
     260    */
    258261  }
    259262 
     
    265268    FlatFileParser.Data data, int multiLineNum)
    266269  {
    267     if (parentMapper != null && extract.isPooled())
     270    if (parentMapper != null) // && extract.isPooled())
    268271    {
    269272      String nameOrId = parentMapper.getValue(data);
  • trunk/src/plugins/core/net/sf/basedb/plugins/batchimport/SampleImporter.java

    r5662 r5663  
    297297    if (pooledMapper != null)
    298298    {
    299       sample.setPooled(Values.getBoolean(pooledMapper.getValue(data)));
     299      //sample.setPooled(Values.getBoolean(pooledMapper.getValue(data)));
    300300    }
    301301    if (protocolMapper != null)
    302302    {
    303303      String nameOrId = protocolMapper.getValue(data);
    304       ItemSubtype type = ItemSubtype.getRelatedSubtype(dc, sample, Item.PROTOCOL,
    305           SystemItems.getId(sample.isPooled() ? Protocol.POOLING : Protocol.SAMPLING));
     304      ItemSubtype type = ItemSubtype.getRelatedSubtype(dc, sample, Item.PROTOCOL, SystemItems.getId(Protocol.SAMPLING));
    306305      Protocol protocol = findProtocol(dc, FallbackIdMethod.NAME_OR_EXTERNALID_OR_ID, nameOrId, type);
    307306      if (nameOrId == null || protocol != null) creationEvent.setProtocol(protocol);
     
    319318      }
    320319    }
     320    /*
    321321    if (!sample.isPooled())
    322322    {
     323    */
    323324      if (parentMapper != null)
    324325      {
     
    326327        ItemSubtype type = ItemSubtype.getRelatedSubtype(dc, sample, Item.BIOSOURCE, 0);
    327328        BioSource bioSource = findBioSource(dc, FallbackIdMethod.NAME_OR_EXTERNALID_OR_ID, nameOrId, type);
    328         if (nameOrId == null || bioSource != null) sample.setBioSource(bioSource);
     329        if (nameOrId == null || bioSource != null) sample.getCreationEvent().setSource(bioSource);
    329330      }
     331      /*
    330332    }
    331333    else
     
    333335      updateMultiLineItem(dc, sample, data, 0);
    334336    }
     337    */
    335338  }
    336339 
     
    342345    FlatFileParser.Data data, int multiLineNum)
    343346  {
    344     if (parentMapper != null && sample.isPooled())
     347    if (parentMapper != null) // && sample.isPooled())
    345348    {
    346349      String nameOrId = parentMapper.getValue(data);
  • trunk/src/test/TestExtract.java

    r5662 r5663  
    2323*/
    2424import net.sf.basedb.core.*;
    25 
     25import net.sf.basedb.core.query.ResultList;
     26import net.sf.basedb.util.biomaterial.ChildrenTransformer;
     27import net.sf.basedb.util.biomaterial.ExtractToSampleTransformer;
     28import net.sf.basedb.util.biomaterial.ParentsTransformer;
     29import net.sf.basedb.util.biomaterial.SampleToExtractTransformer;
     30
     31import java.util.Collections;
    2632import java.util.Date;
     33import java.util.LinkedHashSet;
    2734import java.util.Set;
    2835
     
    4754    int tagId = TestTag.test_create("Test", SystemItems.getId(Tag.LABEL), true);
    4855    int id = test_create(0, "Extract #1 (standalone)", 0, 0, true);
    49     int id2 = test_create(sampleId, "Extract #2", 0, 0, false);
    50     int id3 = test_create(id2, "Extract #3 (labeled)", SystemItems.getId(Extract.LABELED), tagId, false);
    51     int id4 = test_create_pooled(id, id2, id3);
    52 
     56    int id2 = test_create(sampleId, "Extract #2 (sample parent)", 0, 0, false);
     57    int id3 = test_create(id, "Extract #3 (extract parent+labeled)", SystemItems.getId(Extract.LABELED), tagId, false);
     58    int id4 = test_create_pooled("Extract #4 (pooled)", id, id2, id3);
     59
     60 
    5361    test_load(id);
    5462    test_list(-1);
     
    5664    write_events_header();
    5765    test_add_event(id, 100.0f);
    58     test_list_events(id, 3);  // creation event, pooling event for id4, and extra event
     66    test_list_events(id, 4);  // creation event, create event for id3+id4, and extra event
    5967   
    60     write_sources_header();
    61     test_list_sources(id3, 1); // The sample
    62     test_list_sources(id4, 3); // The three id, id2 and id3 extracts
    63     test_list_pooledChildren(id2, 2);
    64 
     68    write_parents_header();
     69    test_list_sources(id4, 3); // The three id, id2 and id3 samples
     70    test_list_children(id, 2); // id3 and id4
     71
     72    // Transformers
     73    test_childrenTransformer(id, 2);
     74    test_parentsTransformer(id4, 3);
     75    test_extractToSampleTransformer(id2, 1);
     76    test_sampleToExtractTransformer(sampleId, 1);
     77
     78   
    6579    if (TestUtil.waitBeforeDelete()) TestUtil.waitForEnter();
    6680    // Standard test: Delete
     
    94108      {
    95109        BioMaterial parent = BioMaterial.getById(dc, parentId);
    96         if (parent.getType() == Item.SAMPLE)
    97         {
    98           Sample s = (Sample)parent;
    99           e.setSample(s).setUsedQuantity(200.0f);
    100         }
    101         else
    102         {
    103           e.setPooled(true);
    104           e.getCreationEvent().addSource(parent).setUsedQuantity(200.0f);
    105         }
     110        BioMaterialEventSource evtSrc = e.getCreationEvent().setSource(parent);
     111        evtSrc.setUsedQuantity(200.0f);
    106112      }
    107113      if (subtypeId > 0)
     
    134140  }
    135141
    136   static int test_create_pooled(int... sourceIds)
     142  static int test_create_pooled(String name, int... sourceIds)
    137143  {
    138144    if (!TestUtil.hasPermission(Permission.CREATE, Item.EXTRACT)) return 0;
     
    143149      dc = TestUtil.getDbControl();
    144150      Extract e = Extract.getNew(dc);
    145       e.setName("Test pooled extract");
     151      e.setName(name);
    146152      e.setDescription("Added at "+new Date());
    147153      e.setExternalId("POOLED-455-EXTRACT");
    148154      e.setOriginalQuantity(500.0f);
    149       e.setPooled(true);
    150155      BioMaterialEvent evt = e.getCreationEvent();
    151156      for (int sourceId : sourceIds)
     
    289294    if (!TestUtil.getSilent())
    290295    {
    291       write("   \tID \tName      \tSubtype\tDescription\tExternal id\tPooled\tSample\tTag\tQuantity\tRemain");
    292       write("-- \t-- \t--------- \t-------\t-----------\t-----------\t------\t------\t---\t--------\t------");
     296      write("   \tID \tName      \tSubtype\tDescription\tExternal id\tParent type\tParent\tTag\tQuantity\tRemain");
     297      write("-- \t-- \t--------- \t-------\t-----------\t-----------\t-----------\t------\t---\t--------\t------");
    293298    }
    294299  }
     
    297302  {
    298303    if (!TestUtil.getSilent()) System.out.println(i+":\t"+e.getId()+"\t"+e.getName()+"\t"+e.getItemSubtype()+"\t"+e.getDescription()+
    299       "\t"+e.getExternalId()+"\t"+e.isPooled()+"\t"+e.getSample()+"\t"+e.getTag()+"\t"+e.getOriginalQuantity()+"\t"+e.getRemainingQuantity());
     304      "\t"+e.getExternalId()+"\t"+e.getParentType()+"\t"+e.getParent()+"\t"+e.getTag()+"\t"+e.getOriginalQuantity()+"\t"+e.getRemainingQuantity());
    300305  }
    301306  static void write_events_header()
     
    318323    if (!TestUtil.getSilent()) System.out.println(i+":\t"+h.getId()+"\t"+h.getName()+"\t"+h.getDescription());
    319324  }
    320   static void write_sources_header()
     325
     326  static void write_parents_header()
    321327  {
    322328    if (!TestUtil.getSilent())
    323329    {
    324       write("   \tID \tName      \tDescription\tExternal id\tPooled\tQuantity\tRemain\tUsed");
    325       write("-- \t-- \t--------- \t-----------\t-----------\t------\t--------\t------\t----");
    326     }
    327   }
     330      write("   \tID \tName      \tDescription\tExternal id\tQuantity\tRemain\tUsed");
     331      write("-- \t-- \t--------- \t-----------\t-----------\t--------\t------\t----");
     332    }
     333  }
     334
    328335  static void write_item(int i, MeasuredBioMaterial b, BioMaterialEvent evt)
    329336    throws BaseException
    330337  {
    331338    if (!TestUtil.getSilent()) System.out.println(i+":\t"+b.getId()+"\t"+b.getName()+"\t"+b.getDescription()+
    332       "\t"+b.getExternalId()+"\t"+b.isPooled()+"\t"+b.getOriginalQuantity()+"\t"+b.getRemainingQuantity()+
     339      "\t"+b.getExternalId()+"\t"+b.getParentType()+"\t"+b.getOriginalQuantity()+"\t"+b.getRemainingQuantity()+
    333340      "\t"+evt.getUsedQuantity(b));
    334341  }
     
    402409    }
    403410  }
    404 
     411 
    405412  static void test_list_sources(int extractId, int expectedResults)
    406413  {
     
    412419      Extract e = Extract.getById(dc, extractId);
    413420      BioMaterialEvent evt = e.getCreationEvent();
    414       ItemResultList<? extends MeasuredBioMaterial> l = evt.getSources().list(dc);
     421      ResultList<BioMaterialEventSource> l = evt.getEventSources().list(dc);
    415422      for (int i = 0; i<l.size(); i++)
    416423      {
    417         write_item(i, l.get(i), evt);
     424        TestSample.write_item(i, l.get(i));
    418425      }
    419426      if (expectedResults >= 0 && expectedResults != l.size())
     
    434441    }
    435442  }
    436   static void test_list_pooledChildren(int extractId, int expectedResults)
     443
     444  static void test_list_children(int extractId, int expectedResults)
    437445  {
    438446    if (extractId == 0) return;
     
    442450      dc = TestUtil.getDbControl();
    443451      Extract e = Extract.getById(dc, extractId);
    444       ItemResultList<BioMaterialEvent> ev = e.getPoolingEvents().list(dc);
     452      ItemResultList<Extract> ev = e.getChildExtracts().list(dc);
    445453     
    446454      for (int i=0; i<ev.size(); i++)
    447455      {
    448         write_item(i, (Extract)ev.get(i).getBioMaterial());
     456        write_item(i, ev.get(i));
    449457      }
    450458      if (expectedResults >= 0 && expectedResults != ev.size())
     
    452460        throw new BaseException("Expected "+expectedResults+" results, not "+ev.size());
    453461      }
    454       write("--List pools from extract OK ("+ev.size()+")");
    455     }
    456     catch (Throwable ex)
    457     {
    458       write("--List pools for extract FAILED");
    459       ex.printStackTrace();
    460       ok = false;
    461     }
    462     finally
    463     {
    464       if (dc != null) dc.close();
    465     }
    466   }
     462      write("--List children for extract OK ("+ev.size()+")");
     463    }
     464    catch (Throwable ex)
     465    {
     466      write("--List children for extract FAILED");
     467      ex.printStackTrace();
     468      ok = false;
     469    }
     470    finally
     471    {
     472      if (dc != null) dc.close();
     473    }
     474  }
     475
    467476 
    468477  static void test_list_bioassays(int extractId, int expectedResults)
     
    497506  }
    498507 
     508 
     509  static void test_childrenTransformer(int extractId, int expectedResults)
     510  {
     511    if (extractId == 0) return;
     512    DbControl dc = null;
     513    try
     514    {
     515      dc = TestUtil.getDbControl();
     516      Extract e = Extract.getById(dc, extractId);
     517      ChildrenTransformer<Extract> pct = new ChildrenTransformer<Extract>(dc, false, Extract.getQuery());
     518      Set<Extract> children = new LinkedHashSet<Extract>();
     519      pct.transform(Collections.singleton(e), children);
     520
     521      int i = 0;
     522      for (Extract c : children)
     523      {
     524        write_item(i, c);
     525        i++;
     526      }
     527      if (expectedResults >= 0 && expectedResults != children.size())
     528      {
     529        throw new BaseException("Expected "+expectedResults+" results, not "+children.size());
     530      }
     531      write("--List children for extract using transformer OK ("+children.size()+")");
     532    }
     533    catch (Throwable ex)
     534    {
     535      write("--List children for extract using transformer FAILED");
     536      ex.printStackTrace();
     537      ok = false;
     538    }
     539    finally
     540    {
     541      if (dc != null) dc.close();
     542    }
     543  }
     544
     545  static void test_parentsTransformer(int extractId, int expectedResults)
     546  {
     547    if (extractId == 0) return;
     548    DbControl dc = null;
     549    try
     550    {
     551      dc = TestUtil.getDbControl();
     552      Extract e = Extract.getById(dc, extractId);
     553      ParentsTransformer<Extract> pct = new ParentsTransformer<Extract>(dc, false, Extract.getQuery());
     554      Set<Extract> parents = new LinkedHashSet<Extract>();
     555      pct.transform(Collections.singleton(e), parents);
     556
     557      int i = 0;
     558      for (Extract c : parents)
     559      {
     560        write_item(i, c);
     561        i++;
     562      }
     563      if (expectedResults >= 0 && expectedResults != parents.size())
     564      {
     565        throw new BaseException("Expected "+expectedResults+" results, not "+parents.size());
     566      }
     567      write("--List parents for extract using transformer OK ("+parents.size()+")");
     568    }
     569    catch (Throwable ex)
     570    {
     571      write("--List parents for extract using transformer FAILED");
     572      ex.printStackTrace();
     573      ok = false;
     574    }
     575    finally
     576    {
     577      if (dc != null) dc.close();
     578    }
     579  }
     580
     581  static void test_extractToSampleTransformer(int extractId, int expectedResults)
     582  {
     583    if (extractId == 0) return;
     584    DbControl dc = null;
     585    try
     586    {
     587      dc = TestUtil.getDbControl();
     588      Extract e = Extract.getById(dc, extractId);
     589      ExtractToSampleTransformer pct = new ExtractToSampleTransformer(dc);
     590      Set<Sample> parents = new LinkedHashSet<Sample>();
     591      pct.transform(Collections.singleton(e), parents);
     592
     593      int i = 0;
     594      for (Sample c : parents)
     595      {
     596        TestSample.write_item(i, c);
     597        i++;
     598      }
     599      if (expectedResults >= 0 && expectedResults != parents.size())
     600      {
     601        throw new BaseException("Expected "+expectedResults+" results, not "+parents.size());
     602      }
     603      write("--List sample for extract using transformer OK ("+parents.size()+")");
     604    }
     605    catch (Throwable ex)
     606    {
     607      write("--List sample for extract using transformer FAILED");
     608      ex.printStackTrace();
     609      ok = false;
     610    }
     611    finally
     612    {
     613      if (dc != null) dc.close();
     614    }
     615  }
     616
     617  static void test_sampleToExtractTransformer(int sampleId, int expectedResults)
     618  {
     619    if (sampleId == 0) return;
     620    DbControl dc = null;
     621    try
     622    {
     623      dc = TestUtil.getDbControl();
     624      Sample s = Sample.getById(dc, sampleId);
     625      SampleToExtractTransformer pct = new SampleToExtractTransformer(dc);
     626      Set<Extract> children = new LinkedHashSet<Extract>();
     627      pct.transform(Collections.singleton(s), children);
     628
     629      int i = 0;
     630      for (Extract c : children)
     631      {
     632        write_item(i, c);
     633        i++;
     634      }
     635      if (expectedResults >= 0 && expectedResults != children.size())
     636      {
     637        throw new BaseException("Expected "+expectedResults+" results, not "+children.size());
     638      }
     639      write("--List extracts for sample using transformer OK ("+children.size()+")");
     640    }
     641    catch (Throwable ex)
     642    {
     643      write("--List extracts for sample using transformer FAILED");
     644      ex.printStackTrace();
     645      ok = false;
     646    }
     647    finally
     648    {
     649      if (dc != null) dc.close();
     650    }
     651  }
     652 
     653 
    499654}
  • trunk/src/test/TestGenericOverview.java

    r5657 r5663  
    100100    int extract1 = TestExtract.test_create(sample1, "Extract GO #1", 0, 0, false);
    101101    int extract2 = TestExtract.test_create(sample2, "Extract GO #2", 0, 0, false);
    102     int extractPooled = TestExtract.test_create_pooled(extract1, extract2);
     102    int extractPooled = TestExtract.test_create_pooled("Extract GO #3 (pooled)", extract1, extract2);
    103103   
    104104    // Array design
  • trunk/src/test/TestPhysicalBioAssay.java

    r5662 r5663  
    251251      StringBuilder sb = new StringBuilder();
    252252      sb.append("[");
    253       for (MeasuredBioMaterial le : h.getCreationEvent().getSources().list(h.getDbControl()))
     253      for (BioMaterial le : h.getCreationEvent().getSources().list(h.getDbControl()))
    254254      {
    255255        sb.append(le.toString());
  • trunk/src/test/TestSample.java

    r5662 r5663  
    2323*/
    2424import net.sf.basedb.core.*;
    25 import net.sf.basedb.util.biomaterial.PooledChildrenTransformer;
    26 
    27 import java.util.ArrayList;
     25import net.sf.basedb.core.query.ResultList;
     26import net.sf.basedb.util.biomaterial.BioSourceToSampleTransformer;
     27import net.sf.basedb.util.biomaterial.ChildrenTransformer;
     28import net.sf.basedb.util.biomaterial.ParentsTransformer;
     29import net.sf.basedb.util.biomaterial.SampleToBioSourceTransformer;
     30
    2831import java.util.Collections;
    2932import java.util.Date;
    30 import java.util.List;
     33import java.util.LinkedHashSet;
    3134import java.util.Set;
    3235
     
    4851    write_header();
    4952    // Standard tests: create, load, list
    50     int id = test_create(0, null, true);
    51     int id2 = test_create(0, null, false);
    52    
    5353    int bioSourceId = TestBioSource.test_create(null, false);
    54     int id3 = test_create(bioSourceId, null, false);
    55     int id4 = test_create_pooled(id, id2, id3);
     54    int id = test_create(0, "Sample #1 (standalone)", true);
     55    int id2 = test_create(bioSourceId, "Sample #2 (biosource parent)", false);
     56    int id3 = test_create(id, "Sample #3 (sample parent)", false);
     57    int id4 = test_create_pooled("Sample #4 (pooled)", id, id2, id3);
    5658
    5759    test_load(id);
     
    6062    write_events_header();
    6163    test_add_event(id, 100.0f);
    62     test_list_events(id, 3);  // creation event, pooling event for id4, and extra event
     64    test_list_events(id, 4);  // creation event, create event for id3+id4, and extra event
    6365   
    64     write_sources_header();
     66    write_parents_header();
    6567    test_list_sources(id4, 3); // The three id, id2 and id3 samples
    66     test_list_pooledChildren(id2, 1);
    67     test_pooledChildrenTransformer(id2, 1);
     68    test_list_children(id, 2); // id3 and id4
     69
     70    // Transformers
     71    test_childrenTransformer(id, 2);
     72    test_parentsTransformer(id4, 3);
     73    test_sampleToBioSourceTransformer(id2, 1);
     74    test_bioSourceToSampleTransformer(bioSourceId, 1);
    6875
    6976    // Standard test: Delete
     
    7986  }
    8087
    81   static int test_create(int bioSourceId, String name, boolean setAll)
     88  static int test_create(int parentId, String name, boolean setAll)
    8289  {
    8390    if (!TestUtil.hasPermission(Permission.CREATE, Item.SAMPLE)) return 0;
     
    95102        s.setOriginalQuantity(500.0f);
    96103      }
    97       if (bioSourceId != 0)
    98       {
    99         BioSource bs = BioSource.getById(dc, bioSourceId);
    100         s.setBioSource(bs);
    101         s.setName(bs.getName() + ".s");
     104      if (parentId != 0)
     105      {
     106        BioMaterial parent = BioMaterial.getById(dc, parentId);
     107        s.getCreationEvent().setSource(parent);
     108        s.setName(parent.getName() + ".s");
    102109      }
    103110      if (name != null) s.setName(name);
     
    123130  }
    124131
    125   static int test_create_pooled(int... sourceIds)
     132  static int test_create_pooled(String name, int... sourceIds)
    126133  {
    127134    if (!TestUtil.hasPermission(Permission.CREATE, Item.SAMPLE)) return 0;
     
    132139      dc = TestUtil.getDbControl();
    133140      Sample s = Sample.getNew(dc);
    134       s.setName("Test pooled sample");
     141      s.setName(name);
    135142      s.setDescription("Added at "+new Date());
    136143      s.setExternalId("POOLED-455-SAMPLE");
    137144      s.setOriginalQuantity(500.0f);
    138       s.setPooled(true);
    139145      BioMaterialEvent evt = s.getCreationEvent();
    140146      for (int sourceId : sourceIds)
     
    277283    if (!TestUtil.getSilent())
    278284    {
    279       write("   \tID \tName      \tDescription\tExternal id\tBioSource\tQuantity\tRemain");
    280       write("-- \t-- \t--------- \t-----------\t-----------\t---------\t--------\t------");
     285      write("   \tID \tName      \tDescription\tExternal id\tParent\tQuantity\tRemain");
     286      write("-- \t-- \t--------- \t-----------\t-----------\t------\t--------\t------");
    281287    }
    282288  }
     
    285291  {
    286292    if (!TestUtil.getSilent()) System.out.println(i+":\t"+s.getId()+"\t"+s.getName()+"\t"+s.getDescription()+
    287       "\t"+s.getExternalId()+"\t"+s.getBioSource()+"\t"+s.getOriginalQuantity()+"\t"+s.getRemainingQuantity());
     293      "\t"+s.getExternalId()+"\t"+s.getParent()+"\t"+s.getOriginalQuantity()+"\t"+s.getRemainingQuantity());
    288294  }
    289295  static void write_events_header()
     
    301307      "\t"+evt.getEventDate()+"\t"+evt.getEntryDate()+"\t"+evt.getUsedQuantity(s)+"\t"+evt.getComment());
    302308  }
    303   static void write_sources_header()
     309
     310  static void write_parents_header()
    304311  {
    305312    if (!TestUtil.getSilent())
    306313    {
    307       write("   \tID \tName      \tDescription\tExternal id\tPooled\tQuantity\tRemain\tUsed");
    308       write("-- \t-- \t--------- \t-----------\t-----------\t------\t--------\t------\t----");
    309     }
    310   }
    311   static void write_item(int i, MeasuredBioMaterial b, BioMaterialEvent evt)
     314      write("   \tID \tName      \tDescription\tExternal id\tQuantity\tRemain\tUsed");
     315      write("-- \t-- \t--------- \t-----------\t-----------\t--------\t------\t----");
     316    }
     317  }
     318
     319  static void write_item(int i, BioMaterialEventSource evtSrc)
    312320    throws BaseException
    313321  {
    314     if (!TestUtil.getSilent()) System.out.println(i+":\t"+b.getId()+"\t"+b.getName()+"\t"+b.getDescription()+
    315       "\t"+b.getExternalId()+"\t"+b.isPooled()+"\t"+b.getOriginalQuantity()+"\t"+b.getRemainingQuantity()+
    316       "\t"+evt.getUsedQuantity(b));
     322    if (!TestUtil.getSilent())
     323    {
     324      MeasuredBioMaterial bm = (MeasuredBioMaterial)evtSrc.getBioMaterial();
     325      System.out.println(i+":\t"+bm.getId()+"\t"+bm.getName()+"\t"+bm.getDescription()+
     326          "\t"+bm.getExternalId()+"\t"+"\t"+bm.getOriginalQuantity()+"\t"+bm.getRemainingQuantity()+
     327          "\t"+evtSrc.getUsedQuantity());
     328    }
    317329  }
    318330
     
    395407      Sample s = Sample.getById(dc, sampleId);
    396408      BioMaterialEvent evt = s.getCreationEvent();
    397       ItemResultList<? extends MeasuredBioMaterial> l = evt.getSources().list(dc);
     409      ResultList<BioMaterialEventSource> l = evt.getEventSources().list(dc);
    398410      for (int i = 0; i<l.size(); i++)
    399411      {
    400         write_item(i, l.get(i), evt);
     412        write_item(i, l.get(i));
    401413      }
    402414      if (expectedResults >= 0 && expectedResults != l.size())
     
    417429    }
    418430  }
    419   static void test_list_pooledChildren(int sampleId, int expectedResults)
     431
     432  static void test_list_children(int sampleId, int expectedResults)
    420433  {
    421434    if (sampleId == 0) return;
     
    425438      dc = TestUtil.getDbControl();
    426439      Sample s = Sample.getById(dc, sampleId);
    427       ItemResultList<BioMaterialEvent> ev = s.getPoolingEvents().list(dc);
     440      ItemResultList<Sample> ev = s.getChildSamples().list(dc);
    428441     
    429442      for (int i=0; i<ev.size(); i++)
    430443      {
    431         write_item(i, (Sample)ev.get(i).getBioMaterial());
     444        write_item(i, ev.get(i));
    432445      }
    433446      if (expectedResults >= 0 && expectedResults != ev.size())
     
    435448        throw new BaseException("Expected "+expectedResults+" results, not "+ev.size());
    436449      }
    437       write("--List pools from sample OK ("+ev.size()+")");
    438     }
    439     catch (Throwable ex)
    440     {
    441       write("--List pools for sample FAILED");
    442       ex.printStackTrace();
    443       ok = false;
    444     }
    445     finally
    446     {
    447       if (dc != null) dc.close();
    448     }
    449   }
    450 
    451   static void test_pooledChildrenTransformer(int sampleId, int expectedResults)
     450      write("--List children for sample OK ("+ev.size()+")");
     451    }
     452    catch (Throwable ex)
     453    {
     454      write("--List children for sample FAILED");
     455      ex.printStackTrace();
     456      ok = false;
     457    }
     458    finally
     459    {
     460      if (dc != null) dc.close();
     461    }
     462  }
     463 
     464  static void test_childrenTransformer(int sampleId, int expectedResults)
    452465  {
    453466    if (sampleId == 0) return;
     
    457470      dc = TestUtil.getDbControl();
    458471      Sample s = Sample.getById(dc, sampleId);
    459       PooledChildrenTransformer<Sample> pct = new PooledChildrenTransformer<Sample>(dc, false, Sample.getQuery());
    460       List<Sample> children = new ArrayList<Sample>();
    461       int numAdded = pct.transform(Collections.singleton(s), children);
    462 
    463       for (int i=0; i<children.size(); i++)
    464       {
    465         write_item(i, children.get(i));
    466       }
    467       if (expectedResults >= 0 && expectedResults != numAdded && numAdded != children.size())
    468       {
    469         throw new BaseException("Expected "+expectedResults+" results, not "+numAdded);
    470       }
    471       write("--List pools from sample using transformer OK ("+numAdded+")");
    472     }
    473     catch (Throwable ex)
    474     {
    475       write("--List pools for sample using transformer FAILED");
    476       ex.printStackTrace();
    477       ok = false;
    478     }
    479     finally
    480     {
    481       if (dc != null) dc.close();
    482     }
    483   }
    484 
     472      ChildrenTransformer<Sample> pct = new ChildrenTransformer<Sample>(dc, false, Sample.getQuery());
     473      Set<Sample> children = new LinkedHashSet<Sample>();
     474      pct.transform(Collections.singleton(s), children);
     475
     476      int i = 0;
     477      for (Sample c : children)
     478      {
     479        write_item(i, c);
     480        i++;
     481      }
     482      if (expectedResults >= 0 && expectedResults != children.size())
     483      {
     484        throw new BaseException("Expected "+expectedResults+" results, not "+children.size());
     485      }
     486      write("--List children for sample using transformer OK ("+children.size()+")");
     487    }
     488    catch (Throwable ex)
     489    {
     490      write("--List children for sample using transformer FAILED");
     491      ex.printStackTrace();
     492      ok = false;
     493    }
     494    finally
     495    {
     496      if (dc != null) dc.close();
     497    }
     498  }
     499
     500  static void test_parentsTransformer(int sampleId, int expectedResults)
     501  {
     502    if (sampleId == 0) return;
     503    DbControl dc = null;
     504    try
     505    {
     506      dc = TestUtil.getDbControl();
     507      Sample s = Sample.getById(dc, sampleId);
     508      ParentsTransformer<Sample> pct = new ParentsTransformer<Sample>(dc, false, Sample.getQuery());
     509      Set<Sample> parents = new LinkedHashSet<Sample>();
     510      pct.transform(Collections.singleton(s), parents);
     511
     512      int i = 0;
     513      for (Sample c : parents)
     514      {
     515        write_item(i, c);
     516        i++;
     517      }
     518      if (expectedResults >= 0 && expectedResults != parents.size())
     519      {
     520        throw new BaseException("Expected "+expectedResults+" results, not "+parents.size());
     521      }
     522      write("--List parents for sample using transformer OK ("+parents.size()+")");
     523    }
     524    catch (Throwable ex)
     525    {
     526      write("--List parents for sample using transformer FAILED");
     527      ex.printStackTrace();
     528      ok = false;
     529    }
     530    finally
     531    {
     532      if (dc != null) dc.close();
     533    }
     534  }
     535
     536  static void test_sampleToBioSourceTransformer(int sampleId, int expectedResults)
     537  {
     538    if (sampleId == 0) return;
     539    DbControl dc = null;
     540    try
     541    {
     542      dc = TestUtil.getDbControl();
     543      Sample s = Sample.getById(dc, sampleId);
     544      SampleToBioSourceTransformer pct = new SampleToBioSourceTransformer(dc);
     545      Set<BioSource> parents = new LinkedHashSet<BioSource>();
     546      pct.transform(Collections.singleton(s), parents);
     547
     548      int i = 0;
     549      for (BioSource c : parents)
     550      {
     551        TestBioSource.write_item(i, c);
     552        i++;
     553      }
     554      if (expectedResults >= 0 && expectedResults != parents.size())
     555      {
     556        throw new BaseException("Expected "+expectedResults+" results, not "+parents.size());
     557      }
     558      write("--List biosource for sample using transformer OK ("+parents.size()+")");
     559    }
     560    catch (Throwable ex)
     561    {
     562      write("--List biosource for sample using transformer FAILED");
     563      ex.printStackTrace();
     564      ok = false;
     565    }
     566    finally
     567    {
     568      if (dc != null) dc.close();
     569    }
     570  }
     571
     572  static void test_bioSourceToSampleTransformer(int bioSourceId, int expectedResults)
     573  {
     574    if (bioSourceId == 0) return;
     575    DbControl dc = null;
     576    try
     577    {
     578      dc = TestUtil.getDbControl();
     579      BioSource bs = BioSource.getById(dc, bioSourceId);
     580      BioSourceToSampleTransformer pct = new BioSourceToSampleTransformer(dc);
     581      Set<Sample> children = new LinkedHashSet<Sample>();
     582      pct.transform(Collections.singleton(bs), children);
     583
     584      int i = 0;
     585      for (Sample c : children)
     586      {
     587        write_item(i, c);
     588        i++;
     589      }
     590      if (expectedResults >= 0 && expectedResults != children.size())
     591      {
     592        throw new BaseException("Expected "+expectedResults+" results, not "+children.size());
     593      }
     594      write("--List sample for biosource using transformer OK ("+children.size()+")");
     595    }
     596    catch (Throwable ex)
     597    {
     598      write("--List sample for biosource using transformer FAILED");
     599      ex.printStackTrace();
     600      ok = false;
     601    }
     602    finally
     603    {
     604      if (dc != null) dc.close();
     605    }
     606  }
     607 
    485608}
  • trunk/src/test/net/sf/basedb/test/roles/UserTest.java

    r5662 r5663  
    376376    sample.setName(name);
    377377    sample.setOriginalQuantity(100.0f);
    378     sample.setBioSource(bioSource);
     378    sample.getCreationEvent().setSource(bioSource);
    379379    sample.getCreationEvent().setProtocol(Util.findProtocol(dc, "Sampling A"));
    380380    dc.saveItem(sample);
     
    398398    extract.setName(name);
    399399    extract.setOriginalQuantity(100.0f);
    400     extract.setSample(sample).setUsedQuantity(50.0f);
     400    extract.getCreationEvent().setSource(sample).setUsedQuantity(50.0f);
    401401    extract.getCreationEvent().setProtocol(Util.findProtocol(dc, "Extraction A"));
    402402    dc.saveItem(extract);
     
    416416    labeledExtract.setOriginalQuantity(100.0f);
    417417    labeledExtract.setTag(label);
    418     labeledExtract.setPooled(true);
    419418    labeledExtract.getCreationEvent().setProtocol(Util.findProtocol(dc, "Labeling A"));
    420     labeledExtract.getCreationEvent().addSource(extract).setUsedQuantity(50.0f);
     419    labeledExtract.getCreationEvent().setSource(extract).setUsedQuantity(50.0f);
    421420    dc.saveItem(labeledExtract);
    422421    return labeledExtract;
  • trunk/www/WEB-INF/base.tld

    r5650 r5663  
    383383    </attribute>
    384384    <attribute>
     385      <name>buttonclass</name>
     386      <required>false</required>
     387      <rtexprvalue>true</rtexprvalue>
     388    </attribute>
     389    <attribute>
     390      <name>buttonstyle</name>
     391      <required>false</required>
     392      <rtexprvalue>true</rtexprvalue>
     393    </attribute>
     394    <attribute>
     395      <name>buttontitle</name>
     396      <required>false</required>
     397      <rtexprvalue>true</rtexprvalue>
     398    </attribute>
     399    <attribute>
     400      <name>buttonicon</name>
     401      <required>false</required>
     402      <rtexprvalue>true</rtexprvalue>
     403    </attribute>
     404    <attribute>
    385405      <name>required</name>
    386406      <required>false</required>
  • trunk/www/biomaterials/biosources/view_biosource.jsp

    r5643 r5663  
    307307      {
    308308        %>
    309         <h4>Samples</h4>
     309        <h4>Child samples</h4>
    310310        No samples have been created from this biosource
    311311        (or, you don't have permission to view them).
     
    317317        <base:section
    318318          id="sampleSection"
    319           title="<%="Samples (" + samples.size() + ")"%>"
     319          title="<%="Child samples (" + samples.size() + ")"%>"
    320320          context="<%=cc%>"
    321321          >
     
    328328            id="name"
    329329            title="Name"
     330          />
     331          <tbl:columndef
     332            id="type"
     333            title="Type"
    330334          />
    331335          <tbl:columndef
     
    347351                    visible="<%=item.isRemoved()%>"
    348352                  /><%=Base.getLinkedName(ID, item, false, true)%></tbl:cell>
     353                  <tbl:cell column="type"><base:propertyvalue item="<%=item%>" property="itemSubtype" /></tbl:cell>
    349354                <tbl:cell column="description"><%=HTML.encodeTags(item.getDescription())%></tbl:cell>
    350355              </tbl:row>
  • trunk/www/biomaterials/events/view_event.jsp

    r5642 r5663  
    3131  import="net.sf.basedb.core.Permission"
    3232  import="net.sf.basedb.core.Plate"
     33  import="net.sf.basedb.core.BioMaterial"
    3334  import="net.sf.basedb.core.BioMaterialEvent"
     35  import="net.sf.basedb.core.BioMaterialEventSource"
    3436  import="net.sf.basedb.core.BioPlateEventParticipant"
    3537  import="net.sf.basedb.core.BioPlateEvent"
     
    4042  import="net.sf.basedb.core.PermissionDeniedException"
    4143  import="net.sf.basedb.core.ItemQuery"
     44  import="net.sf.basedb.core.SpecialQuery"
    4245  import="net.sf.basedb.core.ItemResultList"
    4346  import="net.sf.basedb.core.Include"
     
    4548  import="net.sf.basedb.core.query.Orders"
    4649  import="net.sf.basedb.core.query.Hql"
     50  import="net.sf.basedb.core.query.ResultList"
    4751  import="net.sf.basedb.core.plugin.GuiContext"
    4852  import="net.sf.basedb.core.plugin.Plugin"
     
    277281          <%
    278282        }
    279         ItemQuery<? extends MeasuredBioMaterial> sourcesQuery = event.getSources();
    280         sourcesQuery.include(Include.MINE, Include.SHARED, Include.IN_PROJECT, Include.OTHERS);
    281         sourcesQuery.order(Orders.asc(Hql.property("name")));
    282         ItemResultList<? extends MeasuredBioMaterial> sources = sourcesQuery.list(dc);
     283        SpecialQuery<BioMaterialEventSource> sourcesQuery = event.getEventSources();
     284        sourcesQuery.order(Orders.asc(Hql.property("bioMaterial.name")));
     285        ResultList<BioMaterialEventSource> sources = sourcesQuery.list(dc);
    283286        %>
    284287        <tr>
     
    286289          <td>
    287290          <%
    288           for (MeasuredBioMaterial s : sources)
     291          for (BioMaterialEventSource evtSrc : sources)
    289292          {
    290             Item sourceType = s.getType();
     293            BioMaterial source = null;
     294            Item sourceType = null;
     295            try
     296            {
     297              source = evtSrc.getBioMaterial();
     298              sourceType = source.getType();
     299            }
     300            catch (PermissionDeniedException ex)
     301            {}
    291302            %>
    292             <%=HTML.encodeTags(s.getName())%> (<%=sourceType%>),
    293             <%=Values.formatNumber(event.getUsedQuantity(s), 2, " µg")%>
     303            <%=Base.getLinkedName(ID, source, source == null, true)%>
     304            <%=sourceType != null ? "(" + sourceType + ")" : "" %>
     305            <%=Values.formatNumber(evtSrc.getUsedQuantity(), 2, " µg")%>
    294306            <br>
    295307            <%
  • trunk/www/biomaterials/lists/index.jsp

    r5641 r5663  
    4646  import="net.sf.basedb.util.ShareableUtil"
    4747  import="net.sf.basedb.util.OwnableUtil"
    48   import="net.sf.basedb.util.biomaterial.BioSourceToSampleTransformer"
    49   import="net.sf.basedb.util.biomaterial.SampleToExtractTransformer"
    50   import="net.sf.basedb.util.biomaterial.PooledChildrenTransformer"
    5148  import="net.sf.basedb.util.collections.CollectionTransformer"
    5249  import="net.sf.basedb.util.biomaterial.ListUtil"
  • trunk/www/biomaterials/samples/edit_sample.jsp

    r5650 r5663  
    2929  import="net.sf.basedb.core.DbControl"
    3030  import="net.sf.basedb.core.Item"
     31  import="net.sf.basedb.core.Type"
    3132  import="net.sf.basedb.core.ItemContext"
    3233  import="net.sf.basedb.core.SystemItems"
     
    4748  import="net.sf.basedb.core.query.Orders"
    4849  import="net.sf.basedb.core.query.Hql"
     50  import="net.sf.basedb.core.query.Expressions"
     51  import="net.sf.basedb.core.query.Restrictions"
    4952  import="net.sf.basedb.clients.web.Base"
    5053  import="net.sf.basedb.clients.web.util.HTML"
     
    8184  BioMaterialEvent creationEvent = null;
    8285  Date eventDate = null;
    83   boolean isPooled = false;
     86  Item parentType = null;
    8487  String name = null;
    8588  boolean lockEventProperties = false;
     
    138141    }
    139142    int bioSourceId = Values.getInt(request.getParameter("biosource_id"));
     143    int sampleId = Values.getInt(request.getParameter("sample_id"));
    140144    if (bioSourceId != 0)
    141145    {
    142146      currentBioSource = BioSource.getById(dc, bioSourceId);
    143       isPooled = false;
     147      parentType = Item.BIOSOURCE;
    144148      name = currentBioSource.getName() + ".s" + (currentBioSource.countSamples() + 1);
     149    }
     150    else if (sampleId != 0)
     151    {
     152      parentType = Item.SAMPLE;
     153      Sample s = Sample.getById(dc, sampleId);
     154      name = s.getName() + ".s" + (s.countSamples()+1);
     155      samplesQuery = Sample.getQuery();
     156      samplesQuery.restrict(Restrictions.eq(Hql.property("id"), Expressions.integer(sampleId)));
    145157    }
    146158    else if (Values.getBoolean(request.getParameter("pooled")))
    147159    {   
    148       isPooled = true;
    149       name = Values.getString(cc.getPropertyValue("name"),"New pooled sample");
     160      parentType = Item.SAMPLE;
     161      name = Values.getString(cc.getPropertyValue("name"), "New pooled sample");
     162      samplesQuery = Sample.getQuery();
     163      samplesQuery.restrict(Restrictions.in(Hql.property("id"), Expressions.parameter("selected")));
     164      samplesQuery.setParameter("selected", cc.getSelected(), Type.INT);
    150165    }
    151166    else
    152167    {
    153       isPooled = Values.getBoolean(cc.getPropertyValue("pooled"));
    154168      name = Values.getString(cc.getPropertyValue("name"), "New sample");
    155169    }
     
    165179    creationEvent = sample.getCreationEvent();
    166180    eventDate = creationEvent.getEventDate();
    167     isPooled = sample.isPooled();
     181    parentType = sample.getParentType();
    168182    name = sample.getName();
    169183    lockEventProperties = !creationEvent.hasPermission(Permission.WRITE);
     
    179193    }
    180194
    181    
    182195    try
    183196    {
     
    191204    try
    192205    {
    193       currentBioSource = sample.getBioSource();
     206      if (parentType == Item.BIOSOURCE)
     207      {
     208        currentBioSource = (BioSource)sample.getParent();
     209      }
    194210    }
    195211    catch (PermissionDeniedException ex)
     
    213229    }
    214230 
    215     // Query to retrieve pooled samples
    216     samplesQuery = (ItemQuery<Sample>)creationEvent.getSources();
    217     samplesQuery.include(Include.ALL);
    218     samplesQuery.order(Orders.asc(Hql.property("name")));
     231    // Query to retrieve parent samples
     232    if (parentType == Item.SAMPLE)
     233    {
     234      samplesQuery = (ItemQuery<Sample>)creationEvent.getSources();
     235    }
    219236  }
    220237 
     
    314331      var frm = document.forms['sample'];
    315332      var parents = new Array();
    316       if (frm.pooled[0].checked)
     333      if (frm.parentType[0].checked)
    317334      {
    318335        var bioSourceId = Math.abs(parseInt(frm.biosource_id[frm.biosource_id.selectedIndex].value));
     
    449466    }
    450467   
    451     function pooledOnClick()
    452     {
    453       var frm = document.forms['sample'];
    454       var isPooled = frm.pooled[1].checked
    455       frm.biosource_id.disabled = isPooled;
    456       frm.samples.disabled = !isPooled;
    457       frm.used_quantity.disabled = !isPooled;
     468    function parentTypeOnClick()
     469    {
     470      var frm = document.forms['sample'];
     471      var useSamples = frm.parentType[1].checked
     472      frm.biosource_id.disabled = useSamples;
     473      frm.samples.disabled = !useSamples;
     474      frm.used_quantity.disabled = !useSamples;
    458475      parentsChanged = true;
    459476    }
     
    465482    {
    466483      var frm = document.forms['sample'];
    467       if (frm.pooled[1].checked)
    468       {
    469         alert('This is a pooled sample, which cannot have a biosource as it\'s parent');
    470         return;
    471       }
    472 
    473484      var url = '../biosources/index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectone';
    474485      url += '&callback=setBioSourceCallback&resetTemporary=1';
     
    492503      list[1].text = name;
    493504      list.selectedIndex = 1;
     505
     506      frm.parentType[0].checked = true;
     507      frm.parentType[1].checked = false;
     508      parentTypeOnClick();
    494509      parentsChanged = true;
    495510    }
     
    498513    {
    499514      var frm = document.forms['sample'];
    500       if (!frm.pooled[1].checked)
    501       {
    502         alert('This is not a pooled sample');
    503         return;
    504       }
    505      
    506515      var url = 'index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectmultiple';
    507516      url += '&callback=addSampleCallback&resetTemporary=1';
     
    511520    function addSampleCallback(sampleId, name)
    512521    {
     522      var frm = document.forms['sample'];
    513523      var item = Link.getItem('S', sampleId);
    514524      if (!item) item = new Item('S', sampleId, name+' [-]', '', '');
    515       Link.addItem(document.forms['sample'].samples, item);
     525      Link.addItem(frm.samples, item);
     526      frm.parentType[0].checked = false;
     527      frm.parentType[1].checked = true;
     528      parentTypeOnClick();
    516529      parentsChanged = true;
    517530    }
     
    567580      initBioWell();
    568581      initSamples();
    569       pooledOnClick();   
     582      parentTypeOnClick();   
    570583    }
    571584    function initSamples()
     
    573586      var samples = document.forms['sample'].samples;
    574587      <%
    575       if (sample != null && sample.isPooled())
    576       {
     588      if (samplesQuery != null)
     589      {
     590        samplesQuery.include(Include.ALL);
     591        samplesQuery.order(Orders.asc(Hql.property("name")));
    577592        ItemResultList<Sample> samples = samplesQuery.list(dc);
    578593        for (Sample s : samples)
    579594        {
    580           String usedQuantity = Values.formatNumber(creationEvent.getUsedQuantity(s), -1);
    581           %>
    582           Link.addNewItem(samples, new Item('S', <%=s.getId()%>, '<%=HTML.javaScriptEncode(s.getName())%> [<%=usedQuantity%> µg]', '<%=usedQuantity%>'));
    583           <%
    584         }
    585       }
    586       else if (sample == null && Values.getBoolean(request.getParameter("pooled")))
    587       {
    588         for (int sid : cc.getSelected())
    589         {
    590           Sample sampleToPool = Sample.getById(dc, sid);
    591           %>
    592           Link.addItem(samples, new Item('S', <%=sampleToPool.getId()%>, '<%=HTML.javaScriptEncode(sampleToPool.getName())%> [-]', '', ''));
    593           <%
     595          if (sample != null)
     596          {
     597            String usedQuantity = Values.formatNumber(creationEvent.getUsedQuantity(s), -1);
     598            %>
     599            Link.addNewItem(samples, new Item('S', <%=s.getId()%>, '<%=HTML.javaScriptEncode(s.getName())%> [<%=usedQuantity%> µg]', '<%=usedQuantity%>'));
     600            <%
     601          }
     602          else
     603          {
     604            %>
     605            Link.addItem(samples, new Item('S', <%=s.getId()%>, '<%=HTML.javaScriptEncode(s.getName())%> [-]', '', ''));
     606            <%
     607          }
    594608        }
    595609      }
     
    755769      <table class="form" cellspacing=0>
    756770      <tr>
    757         <td class="prompt">Pooled</td>
     771        <td class="prompt">Parent type</td>
    758772        <td>
    759           <input type="radio" name="pooled" value="0" onclick="pooledOnClick()"
    760             <%=!isPooled ? "checked" : ""%>
    761             >no
    762           <input type="radio" name="pooled" value="1" onclick="pooledOnClick()"
    763             <%=isPooled ? "checked" : ""%>
    764             >yes
     773          <input type="radio" name="parentType" id="parentType.biosource"
     774            value="BIOSOURCE" onclick="parentTypeOnClick()"
     775            <%=parentType != Item.SAMPLE ? "checked" : ""%>
     776            ><label for="parentType.biosource">Biosource</label>
     777          <input type="radio" name="parentType" id="parentType.sample"
     778            value="SAMPLE" onclick="parentTypeOnClick()"
     779            <%=parentType == Item.SAMPLE ? "checked" : ""%>
     780            ><label for="parentType.sample">Sample</label>
    765781        </td>
    766782      </tr>
     
    771787            id="biosource_id"
    772788            clazz="selectionlist"
     789            buttonstyle="width: 150px;"
     790            buttonicon="add.png"
     791            buttontitle="Select biosource&hellip;"
    773792            required="false"
    774793            current="<%=currentBioSource%>"
     
    788807          <tr valign="top">
    789808          <td>
    790             <select name="samples" size="5" multiple style="width: 20em;"
     809            <select name="samples" size="5" multiple class="selectionlist"
    791810              onchange="samplesOnChange()">
    792             </select>&nbsp;<br>
    793             Used
    794             <input <%=clazz%> type="text" name="used_quantity" value=""
    795               size="12" maxlength="10" onkeypress="return Numbers.numberOnly(event)"
    796               onkeyup="usedQuantityOnBlur();"
    797             > (µg)
     811            </select>&nbsp;
    798812            <input type="hidden" name="modifiedSamples" value="">
    799813            <input type="hidden" name="removedSamples" value="">
    800814          </td>
    801815          <td>
    802             <table border="0">
    803             <tr><td width="150"><base:button
     816            <table border="0" cellspacing="0" cellpadding="0">
     817            <tr><td style="padding: 1px 0px 4px 0px; width: 150px;"><base:button
    804818              onclick="addSamplesOnClick()"
    805819              title="Add&nbsp;samples&hellip;"
    806820              tooltip="Add samples"
    807821              /></td></tr>
    808             <tr><td width="150"><base:button
     822            <tr><td><base:button
     823              style="width: 150px;"
    809824              onclick="removeOnClick()"
    810825              title="Remove"
     
    817832        </td>
    818833      </tr>
     834      <tr>
     835        <td class="subprompt">-</td>
     836        <td>used quantity
     837        <input <%=clazz%> type="text" name="used_quantity" value=""
     838              size="12" maxlength="10" onkeypress="return Numbers.numberOnly(event)"
     839              onkeyup="usedQuantityOnBlur();"
     840            > (µg)
     841        </td>
     842      </tr>         
    819843      </table>
    820844    </t:tab>
  • trunk/www/biomaterials/samples/index.jsp

    r5662 r5663  
    8888    cc.setObject("export.formatter.bioWell.row", new WellCoordinateFormatter(true));
    8989    cc.setObject("export.formatter.bioWell.column", new WellCoordinateFormatter(false));
    90     cc.setObject("export.formatter.&creationEvent.sourceBioMaterials(name)", new NameableFormatter());
    91     cc.setObject("export.formatter.&sourceEvents(event.bioMaterial.name)", new NameableFormatter());
     90    cc.setObject("export.formatter.&creationEvent.sources(bioMaterial.name)", new NameableFormatter());
     91    cc.setObject("export.formatter.&childCreationEvents(event.bioMaterial.name)", new NameableFormatter());
    9292    cc.setObject("export.formatter.&children(name)", new NameableFormatter());
    9393   
     
    106106    childSamplesQuery.join(Hql.innerJoin("creationEvent", "ce"));
    107107    childSamplesQuery.join(Hql.innerJoin("ce", "sources", "src"));
    108     childSamplesQuery.restrict(Restrictions.eq(Hql.index("src", null), Expressions.parameter(sampleParameter)));
     108    childSamplesQuery.restrict(Restrictions.eq(Hql.property("src", "bioMaterial"), Expressions.parameter(sampleParameter)));
    109109    childSamplesQuery.order(Orders.asc(Hql.property("name")));
    110110    childSamplesQuery.include(cc.getInclude());
    111     cc.setObject("export.dataloader.&sourceEvents(event.bioMaterial.name)", new ItemQueryLoader(childSamplesQuery, sampleParameter));
     111    cc.setObject("export.dataloader.&childCreationEvents(event.bioMaterial.name)", new ItemQueryLoader(childSamplesQuery, sampleParameter));
    112112   
    113113    // Parent samples
    114114    final ItemQuery<Sample> parentSamplesQuery = Sample.getQuery();
    115     parentSamplesQuery.join(Hql.innerJoin("sourceEvents", "srcevt"));
    116     parentSamplesQuery.join(Hql.innerJoin("srcevt", "event", "evt"));
     115    parentSamplesQuery.join(Hql.innerJoin("childCreationEvents", "cce"));
     116    parentSamplesQuery.join(Hql.innerJoin("cce", "event", "evt"));
    117117    parentSamplesQuery.restrict(Restrictions.eq(Hql.property("evt", "bioMaterial"),  Expressions.parameter(sampleParameter)));
    118118    parentSamplesQuery.order(Orders.asc(Hql.property("name")));
    119119    parentSamplesQuery.include(cc.getInclude());
    120     cc.setObject("export.dataloader.&creationEvent.sourceBioMaterials(name)", new ItemQueryLoader(parentSamplesQuery, sampleParameter));
     120    cc.setObject("export.dataloader.&creationEvent.sources(bioMaterial.name)", new ItemQueryLoader(parentSamplesQuery, sampleParameter));
    121121  }
    122122%>
     
    264264 
    265265      // Parents tab
    266       sample.setPooled(Values.getBoolean(request.getParameter("pooled")));
    267       if (!sample.isPooled())
     266      //sample.setPooled(Values.getBoolean(request.getParameter("pooled")));
     267      Item parentType = Item.valueOf(request.getParameter("parentType"));
     268      if (parentType == Item.BIOSOURCE)
    268269      {
    269270        int bioSourceId = Values.getInt(request.getParameter("biosource_id"), -1);
     
    271272        {
    272273          BioSource bs = bioSourceId == 0 ? null : BioSource.getById(dc, bioSourceId);
    273           sample.setBioSource(bs);
     274          creationEvent.setSource(bs);
    274275          if (bs != null) cc.setRecent(bs, maxRecent);
    275276        }
     
    277278      else
    278279      {
     280        if (sample.getParentType() != Item.SAMPLE)
     281        {
     282          creationEvent.clearSources();
     283        }
    279284        String[] modifiedSamples = Values.getString(request.getParameter("modifiedSamples")).split(",");
    280285        for (int i = 0; i < modifiedSamples.length; ++i)
  • trunk/www/biomaterials/samples/list_samples.jsp

    r5662 r5663  
    110110  childSamplesQuery.join(Hql.innerJoin("creationEvent", "ce"));
    111111  childSamplesQuery.join(Hql.innerJoin("ce", "sources", "src"));
    112   childSamplesQuery.restrict(Restrictions.eq(Hql.index("src", null), Hql.entityParameter("sample", Item.SAMPLE)));
     112  childSamplesQuery.restrict(Restrictions.eq(Hql.property("src", "bioMaterial"), Hql.entityParameter("sample", Item.SAMPLE)));
    113113  childSamplesQuery.order(Orders.asc(Hql.property("name")));
    114114  childSamplesQuery.include(cc.getInclude());
     
    178178      Table.itemOnClick(formId, evt, itemId, '<%=mode.getName()%>', viewItem, editItem, returnSelected);
    179179    }
     180    function newSample(sampleId)
     181    {
     182      Main.viewOrEditItem('<%=ID%>', 'SAMPLE', 0, true, '&sample_id='+sampleId);
     183    }
    180184    function newExtract(sampleId)
    181185    {
     
    374378        formatter="<%=dateFormatter%>"
    375379      />
    376       <tbl:columndef
    377         id="pooled"
    378         property="pooled"
    379         datatype="boolean"
    380         title="Pooled"
    381         sortable="true"
    382         filterable="true"
    383         exportable="true"
    384       />
    385       <tbl:columndef
    386         id="bioSource"
    387         title="Biosource"
    388         property="parent.name"
    389         datatype="string"
    390         sortable="true"
    391         filterable="true"
    392         exportable="true"
    393       />
    394380      <tbl:columndef
    395381        id="parents"
    396         title="Parent samples"
     382        title="Parent items"
    397383        property="&creationEvent.sources(bioMaterial.name)"
     384        sortproperty="parent.name"
    398385        datatype="string"
    399386        filterable="true"
    400387        exportable="true"
     388        sortable="true"
    401389      />
    402390      <tbl:columndef
     
    652640            {
    653641              Sample item = samples.next();
     642              Item parentType = item.getParentType();
    654643              BioMaterialEvent creationEvent = item.getCreationEvent();
    655644              int itemId = item.getId();
     
    717706                <tbl:cell column="originalQuantity"><%=Values.formatNumber(item.getOriginalQuantity(), 2)%></tbl:cell>
    718707                <tbl:cell column="remainingQuantity"><%=Values.formatNumber(item.getRemainingQuantity(), 2)%></tbl:cell>
    719                 <tbl:cell column="pooled"><%=item.isPooled()%></tbl:cell>
    720708                <tbl:cell column="protocol"
    721709                  ><base:propertyvalue
     
    768756                <tbl:cell column="eventDate" value="<%=creationEvent.getEventDate()%>" />
    769757                <tbl:cell column="entryDate" value="<%=creationEvent.getEntryDate()%>" />
    770                 <tbl:cell column="bioSource"><base:propertyvalue item="<%=item%>" property="parent"/></tbl:cell>
    771758                <tbl:cell column="parents">
    772759                  <%
    773                   if (item.isPooled())
     760                  if (item.hasSingleParent() || item.getParentType() == null)
     761                  {
     762                    %>
     763                    <base:propertyvalue item="<%=item%>" property="parent"/>
     764                    <%
     765                  }
     766                  else
    774767                  {
    775768                    String separator = "";
     
    788781                      separator = ", ";
    789782                    }
    790                    
    791783                  }
    792784                  %>
     
    810802                  }
    811803                  %>
     804                  <base:icon
     805                    image="add.png"
     806                    onclick="<%="newSample("+itemId+")"%>"
     807                    tooltip="Create new child sample"
     808                    visible="<%=mode.hasEditLink() && createPermission && usePermission %>"
     809                  />
    812810                </tbl:cell>
    813811                <tbl:cell column="extracts">
  • trunk/www/biomaterials/samples/view_sample.jsp

    r5662 r5663  
    133133      Main.viewOrEditItem('<%=ID%>', 'EXTRACT', 0, true, '&sample_id=<%=itemId%>');
    134134    }
     135    function newSample()
     136    {
     137      Main.viewOrEditItem('<%=ID%>', 'SAMPLE', 0, true, '&sample_id=<%=itemId%>');
     138    }
    135139    function deleteItem()
    136140    {
     
    234238      <tbl:button
    235239        image="add.png"
     240        onclick="newSample()"
     241        title="New child sample&hellip;"
     242        tooltip="Create a new child sample from this sample"
     243        visible="<%=sc.hasPermission(Permission.CREATE, Item.SAMPLE) && usePermission%>"
     244      />
     245      <tbl:button
     246        image="add.png"
    236247        onclick="newExtract()"
    237         title="New extract&hellip;"
     248        title="New child extract&hellip;"
    238249        tooltip="Create a new extract from this sample"
    239250        visible="<%=sc.hasPermission(Permission.CREATE, Item.EXTRACT) && usePermission%>"
     
    312323        <td><%=dateFormatter.format(creationEvent.getEntryDate())%></td>
    313324      </tr>
    314       <%
    315       if (!sample.isPooled())
    316       {
    317         %>
    318         <tr>
    319           <td class="prompt">Biosource</td>
    320           <td><base:propertyvalue item="<%=sample%>" property="parent" /></td>
    321         </tr>
    322         <%
    323       }
    324       %>
    325325      <tr>
    326326        <td class="prompt">Protocol</td>
     
    367367 
    368368      <%
    369       if (sample.isPooled())
    370       {
    371         SpecialQuery<BioMaterialEventSource> sourceQuery = creationEvent.getEventSources();
    372         sourceQuery.order(Orders.asc(Hql.property("bioMaterial.name")));
    373         ResultList<BioMaterialEventSource> sources = sourceQuery.list(dc);
    374         %>
    375         <h4 class="docked">Pooled from samples</h4>
    376         <tbl:table
    377           id="pooled"
    378           clazz="itemlist"
    379           columns="all"
     369      SpecialQuery<BioMaterialEventSource> sourceQuery = creationEvent.getEventSources();
     370      sourceQuery.order(Orders.asc(Hql.property("bioMaterial.name")));
     371      ResultList<BioMaterialEventSource> sources = sourceQuery.list(dc);
     372      if (sources.size() == 0)
     373      {
     374        %>
     375        <%
     376      }
     377      else
     378      {
     379        %>
     380        <base:section
     381          id="parentsSection"
     382          title="<%="Parent items (" + sources.size() + ")"%>"
     383          context="<%=cc%>"
    380384          >
    381         <tbl:columndef
    382           id="name"
    383           title="Name"
    384         />
    385         <tbl:columndef
    386           id="quantity"
    387           title="Used quantity (µg)"
    388         />
    389         <tbl:columndef
    390           id="description"
    391           title="Description"
    392         />
    393         <tbl:data>
    394           <tbl:columns>
    395           </tbl:columns>
    396           <tbl:rows>
    397           <%
    398           for (BioMaterialEventSource item : sources)
    399           {
    400             BioMaterial bm = null;
    401             try
     385          <tbl:table
     386            id="parents"
     387            clazz="itemlist"
     388            columns="all"
     389            >
     390          <tbl:columndef
     391            id="name"
     392            title="Name"
     393          />
     394          <tbl:columndef
     395            id="type"
     396            title="Type"
     397          />
     398          <tbl:columndef
     399            id="quantity"
     400            title="Used quantity (µg)"
     401          />
     402          <tbl:columndef
     403            id="description"
     404            title="Description"
     405          />
     406          <tbl:data>
     407            <tbl:columns>
     408            </tbl:columns>
     409            <tbl:rows>
     410            <%
     411            for (BioMaterialEventSource item : sources)
    402412            {
    403               bm = item.getBioMaterial();
     413              BioMaterial bm = null;
     414              try
     415              {
     416                bm = item.getBioMaterial();
     417              }
     418              catch (PermissionDeniedException ex)
     419              {}
     420              %>
     421              <tbl:row>
     422                <tbl:cell column="name"><base:icon
     423                    image="deleted.gif"
     424                    tooltip="This item has been scheduled for deletion"
     425                    visible="<%=bm != null && bm.isRemoved()%>"
     426                  /><%=Base.getLinkedName(ID, bm, bm == null, true)%></tbl:cell>
     427                <tbl:cell column="type"><%=bm != null ? bm.getType() : "" %></tbl:cell>
     428                <tbl:cell column="quantity"><%=Values.formatNumber(item.getUsedQuantity(), 2)%></tbl:cell>
     429                <tbl:cell column="description"><%=HTML.encodeTags(bm == null ? "" : bm.getDescription())%></tbl:cell>
     430              </tbl:row>
     431              <%
    404432            }
    405             catch (PermissionDeniedException ex)
    406             {}
    407433            %>
    408             <tbl:row>
    409               <tbl:cell column="name"><base:icon
    410                   image="deleted.gif"
    411                   tooltip="This item has been scheduled for deletion"
    412                   visible="<%=bm != null && bm.isRemoved()%>"
    413                 /><%=Base.getLinkedName(ID, bm, bm == null, true)%></tbl:cell>
    414               <tbl:cell column="quantity"><%=Values.formatNumber(item.getUsedQuantity(), 2)%></tbl:cell>
    415               <tbl:cell column="description"><%=HTML.encodeTags(bm == null ? "" : bm.getDescription())%></tbl:cell>
    416             </tbl:row>
    417             <%
    418           }
    419           %>
    420           </tbl:rows>
    421         </tbl:data>
    422         </tbl:table>
     434            </tbl:rows>
     435          </tbl:data>
     436          </tbl:table>
     437        </base:section>
    423438        <%
    424439      }
    425440     
    426441      // Samples this item is pooled in.
    427       ItemQuery<BioMaterialEvent> poolingQuery = sample.getPoolingEvents();
    428       ItemResultList<BioMaterialEvent> poolingEvents = poolingQuery.list(dc);
    429       if (poolingEvents.size() == 0)
    430       {
    431         %>
    432         <h4>Pooled in samples</h4>
    433         No samples have been pooled from this sample
     442      SpecialQuery<BioMaterialEventSource> childQuery = sample.getChildCreationEvents();
     443      childQuery.join(Hql.innerJoin("es", "event", "evt", true));
     444      childQuery.join(Hql.innerJoin("evt", "bioMaterial", "bm", true));
     445      childQuery.order(Orders.asc(Hql.property("bm", "name")));
     446      ResultList<BioMaterialEventSource> children = childQuery.list(dc);
     447      if (children.size() == 0)
     448      {
     449        %>
     450        <h4>Child items</h4>
     451        No child items have been created from this sample
    434452        (or, you don't have permission to view them).
    435453        <%
     
    439457        %>
    440458        <base:section
    441           id="pooledSection"
    442           title="<%="Pooled in samples (" + poolingEvents.size() + ")"%>"
     459          id="childSection"
     460          title="<%="Child items (" + children.size() + ")"%>"
    443461          context="<%=cc%>"
    444462          >
    445463          <tbl:table
    446             id="poolChilds"
     464            id="children"
    447465            clazz="itemlist"
    448466            columns="all"
     
    453471            />
    454472            <tbl:columndef
    455               id="quantity"
    456               title="Original quantity (µg)"
     473              id="type"
     474              title="Type"
    457475            />
    458476            <tbl:columndef
    459               id="parents"
    460               title="Used samples[quantity]"
     477              id="quantity"
     478              title="Used quantity (µg)"
    461479            />
    462480            <tbl:columndef
     
    468486              <tbl:rows>
    469487              <%
    470               for (BioMaterialEvent poolingEvt : poolingEvents)
     488              for (BioMaterialEventSource item : children)
    471489              {
    472                 Sample child = (Sample)poolingEvt.getBioMaterial();
    473                 ItemQuery<Sample> samplesQuery = (ItemQuery<Sample>)poolingEvt.getSources();
    474                 samplesQuery.include(Include.ALL);
    475                 samplesQuery.order(Orders.asc(Hql.property("name")));
    476                 ItemResultList<Sample> parentSamples = samplesQuery.list(dc);
     490                BioMaterial bm = null;
     491                try
     492                {
     493                  bm = item.getEvent().getBioMaterial();
     494                }
     495                catch (PermissionDeniedException ex)
     496                {}
    477497                %>
    478498                <tbl:row>
    479                   <tbl:cell column="name">
    480                     <base:icon
     499                  <tbl:cell column="name"><base:icon
    481500                      image="deleted.gif"
    482501                      tooltip="This item has been scheduled for deletion"
    483                       visible="<%=child.isRemoved()%>"
    484                     />
    485                     <%=Base.getLinkedName(ID, child, false, true)%>
    486                   </tbl:cell>
    487                   <tbl:cell column="quantity"><%=Values.formatNumber(child.getOriginalQuantity(), 2)%></tbl:cell>
    488                   <tbl:cell column="parents">
    489                   <%
    490                   String separator = "";
    491                   for (Sample parent : parentSamples)
    492                   {
    493                     out.write(separator);
    494                     if (parent.equals(sample))
    495                         out.write(HTML.encodeTags(parent.getName()));
    496                     else                   
    497                       out.write(Base.getLinkedName(ID, parent, false, true));
    498                     out.write("[" + Values.formatNumber(poolingEvt.getUsedQuantity(parent), 2) + "µg]");
    499                     separator = ", ";
    500                   }
    501                   %>
    502                   </tbl:cell>
    503                   <tbl:cell column="description"><%=HTML.encodeTags(child.getDescription())%></tbl:cell>
     502                      visible="<%=bm != null && bm.isRemoved()%>"
     503                    /><%=Base.getLinkedName(ID, bm, bm == null, true)%></tbl:cell>
     504                  <tbl:cell column="type"><%=bm != null ? bm.getType() : "" %></tbl:cell>
     505                  <tbl:cell column="quantity"><%=Values.formatNumber(item.getUsedQuantity(), 2)%></tbl:cell>
     506                  <tbl:cell column="description"><%=HTML.encodeTags(bm == null ? "" : bm.getDescription())%></tbl:cell>
    504507                </tbl:row>
    505508                <%
     
    512515        <%
    513516      }
    514        
    515       // Extracts created from this sample
    516       ItemQuery<Extract> extractQuery = sample.getExtracts();
    517       extractQuery.include(Include.ALL);
    518       extractQuery.order(Orders.asc(Hql.property("name")));
    519       ItemResultList<Extract> extracts = extractQuery.list(dc);
    520       if (extracts.size() == 0)
    521       {
    522         %>
    523         <h4>Extracts</h4>
    524         No extracts have been created from this sample
    525         (or, you don't have permission to view them).
    526         <%
    527       }
    528       else
    529       {
    530         %>
    531         <base:section
    532           id="extractSection"
    533           title="<%="Extracts (" + extracts.size() + ")"%>"
    534           context="<%=cc%>"
    535           >
    536           <tbl:table
    537             id="extracts"
    538             clazz="itemlist"
    539             columns="all"
    540             >
    541             <tbl:columndef
    542               id="name"
    543               title="Name"
    544             />
    545             <tbl:columndef
    546               id="quantity"
    547               title="Used quantity (µg)"
    548             />
    549             <tbl:columndef
    550               id="description"
    551               title="Description"
    552             />
    553             <tbl:data>
    554               <tbl:columns></tbl:columns>
    555               <tbl:rows>
    556                 <%
    557                 for (Extract e : extracts)
    558                 {
    559                   %>
    560                   <tbl:row>
    561                     <tbl:cell column="name"><base:icon
    562                     image="deleted.gif"
    563                     tooltip="This item has been scheduled for deletion"
    564                     visible="<%=e.isRemoved()%>"
    565                   /><%=Base.getLinkedName(ID, e, false, true)%></tbl:cell>
    566                     <tbl:cell column="quantity"><%=Values.formatNumber(e.getCreationEvent().getUsedQuantity(sample), 2)%></tbl:cell>
    567                     <tbl:cell column="description"><%=HTML.encodeTags(e.getDescription())%></tbl:cell>
    568                   </tbl:row>
    569                   <%
    570                 }
    571                 %>
    572               </tbl:rows>
    573             </tbl:data>
    574           </tbl:table>
    575         </base:section>
    576         <%
    577       }     
    578517      %>
    579518      <jsp:include page="../../common/anytoany/list_anytoany.jsp">
  • trunk/www/include/styles/main.css

    r5643 r5663  
    345345}
    346346
    347 .buttonclass_hover {
     347.buttonclass:hover {
    348348  background: #F0F0F0;
    349349  border-top: 1px solid #333333;
Note: See TracChangeset for help on using the changeset viewer.