src/core/net/sf/basedb/util/listable/ExtractToParentExtractTransformer.java

Code
Comments
Other
Rev Date Author Line
6775 17 Mar 15 nicklas 1 /**
6775 17 Mar 15 nicklas 2   $Id$
6775 17 Mar 15 nicklas 3
6775 17 Mar 15 nicklas 4   Copyright (C) 2015 Nicklas Nordborg
6775 17 Mar 15 nicklas 5
6775 17 Mar 15 nicklas 6   This file is part of BASE - BioArray Software Environment.
6775 17 Mar 15 nicklas 7   Available at http://base.thep.lu.se/
6775 17 Mar 15 nicklas 8
6775 17 Mar 15 nicklas 9   BASE is free software; you can redistribute it and/or
6775 17 Mar 15 nicklas 10   modify it under the terms of the GNU General Public License
6775 17 Mar 15 nicklas 11   as published by the Free Software Foundation; either version 3
6775 17 Mar 15 nicklas 12   of the License, or (at your option) any later version.
6775 17 Mar 15 nicklas 13
6775 17 Mar 15 nicklas 14   BASE is distributed in the hope that it will be useful,
6775 17 Mar 15 nicklas 15   but WITHOUT ANY WARRANTY; without even the implied warranty of
6775 17 Mar 15 nicklas 16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
6775 17 Mar 15 nicklas 17   GNU General Public License for more details.
6775 17 Mar 15 nicklas 18
6775 17 Mar 15 nicklas 19   You should have received a copy of the GNU General Public License
6775 17 Mar 15 nicklas 20   along with BASE. If not, see <http://www.gnu.org/licenses/>.
6775 17 Mar 15 nicklas 21 */
6775 17 Mar 15 nicklas 22 package net.sf.basedb.util.listable;
6775 17 Mar 15 nicklas 23
6775 17 Mar 15 nicklas 24 import java.util.HashSet;
6775 17 Mar 15 nicklas 25 import java.util.Set;
6775 17 Mar 15 nicklas 26
6775 17 Mar 15 nicklas 27 import net.sf.basedb.core.DbControl;
6775 17 Mar 15 nicklas 28 import net.sf.basedb.core.Extract;
6775 17 Mar 15 nicklas 29 import net.sf.basedb.core.Item;
6775 17 Mar 15 nicklas 30 import net.sf.basedb.core.ItemQuery;
6775 17 Mar 15 nicklas 31 import net.sf.basedb.core.query.Expressions;
6775 17 Mar 15 nicklas 32 import net.sf.basedb.core.query.Hql;
6775 17 Mar 15 nicklas 33 import net.sf.basedb.core.query.Restrictions;
6775 17 Mar 15 nicklas 34
6775 17 Mar 15 nicklas 35 /**
6775 17 Mar 15 nicklas 36   Source item transformer implementation that transform extract items to their
6775 17 Mar 15 nicklas 37   parent extract items. From the given set of extract ID:s the transformer will
6775 17 Mar 15 nicklas 38   recursively load as many parent extracts as possible. The source items
6775 17 Mar 15 nicklas 39   may optionally be included in the target set.
6775 17 Mar 15 nicklas 40
6775 17 Mar 15 nicklas 41   @author Nicklas
6775 17 Mar 15 nicklas 42   @since 3.5
6775 17 Mar 15 nicklas 43 */
6775 17 Mar 15 nicklas 44 public class ExtractToParentExtractTransformer 
6775 17 Mar 15 nicklas 45   extends AbstractSourceItemTransformer
6775 17 Mar 15 nicklas 46 {
6775 17 Mar 15 nicklas 47
6775 17 Mar 15 nicklas 48   private final boolean includeSourcesInTarget;
6791 23 Mar 15 nicklas 49   private CollectExtracts collectedExtracts;
7772 17 Feb 20 nicklas 50   private boolean pushOnly;
6775 17 Mar 15 nicklas 51   
6775 17 Mar 15 nicklas 52   /**
6775 17 Mar 15 nicklas 53     Create a new extract to parent extract transformer.
6775 17 Mar 15 nicklas 54     @param includeSourcesInTarget TRUE to include the source items in the target
6775 17 Mar 15 nicklas 55   */
6775 17 Mar 15 nicklas 56   public ExtractToParentExtractTransformer(boolean includeSourcesInTarget) 
6775 17 Mar 15 nicklas 57   {
6775 17 Mar 15 nicklas 58     super(Item.EXTRACT, Item.EXTRACT);
6775 17 Mar 15 nicklas 59     this.includeSourcesInTarget = includeSourcesInTarget;
6775 17 Mar 15 nicklas 60   }
6775 17 Mar 15 nicklas 61   
6791 23 Mar 15 nicklas 62   /**
7772 17 Feb 20 nicklas 63     Create a new extract to parent extract transformer that only load parents
7772 17 Feb 20 nicklas 64     to extracts that has a subtype with "push annotations" set. This functionality
7772 17 Feb 20 nicklas 65     should only be used in the first transformation step.
7772 17 Feb 20 nicklas 66     @see PushToParentsTransformer
7772 17 Feb 20 nicklas 67     @since 3.16
7772 17 Feb 20 nicklas 68   */
7772 17 Feb 20 nicklas 69   public ExtractToParentExtractTransformer(boolean includeSourcesInTarget, boolean childrensThatPushOnly)
7772 17 Feb 20 nicklas 70   {
7772 17 Feb 20 nicklas 71     this(includeSourcesInTarget);
7772 17 Feb 20 nicklas 72     this.pushOnly = childrensThatPushOnly;
7772 17 Feb 20 nicklas 73   }
7772 17 Feb 20 nicklas 74   
7772 17 Feb 20 nicklas 75   /**
6791 23 Mar 15 nicklas 76     Create a new extract to parent extract transformer that is considering
6791 23 Mar 15 nicklas 77     extracts collected on downstream derived and raw bioassays.
6791 23 Mar 15 nicklas 78     @param includeSourcesInTarget TRUE to include the source items in the target
6791 23 Mar 15 nicklas 79     @param collectedExtracts Information about extracts found on downstream derived and raw bioassays
6791 23 Mar 15 nicklas 80    */
6791 23 Mar 15 nicklas 81   public ExtractToParentExtractTransformer(boolean includeSourcesInTarget, CollectExtracts collectedExtracts) 
6791 23 Mar 15 nicklas 82   {
6791 23 Mar 15 nicklas 83     this(includeSourcesInTarget);
6791 23 Mar 15 nicklas 84     this.collectedExtracts = collectedExtracts;
6791 23 Mar 15 nicklas 85   }
6791 23 Mar 15 nicklas 86   
6775 17 Mar 15 nicklas 87   @Override
6775 17 Mar 15 nicklas 88   public Set<Integer> transform(TransformContext context, Set<Integer> source) 
6775 17 Mar 15 nicklas 89   {
6775 17 Mar 15 nicklas 90     DbControl dc = context.getDbControl();
6775 17 Mar 15 nicklas 91     
6775 17 Mar 15 nicklas 92     ItemQuery<Extract> query = Extract.getQuery();
6848 13 Apr 15 nicklas 93     query.setIncludes(context.getInclude());
6775 17 Mar 15 nicklas 94     query.join(Hql.innerJoin("childCreationEvents", "ce"));
6775 17 Mar 15 nicklas 95     query.join(Hql.innerJoin("ce", "event", "evt"));
6775 17 Mar 15 nicklas 96     query.join(Hql.innerJoin("evt", "bioMaterial", "bm"));
6775 17 Mar 15 nicklas 97     query.restrict(
6775 17 Mar 15 nicklas 98       Restrictions.in(
6775 17 Mar 15 nicklas 99         Hql.alias("bm"), 
6775 17 Mar 15 nicklas 100         Expressions.parameter("children")
6775 17 Mar 15 nicklas 101       )
6775 17 Mar 15 nicklas 102     );
7772 17 Feb 20 nicklas 103     if (pushOnly)
7772 17 Feb 20 nicklas 104     {
7772 17 Feb 20 nicklas 105       query.join(Hql.innerJoin("bm", "itemSubtype", "st"));
7772 17 Feb 20 nicklas 106       query.restrict(Restrictions.eq(Hql.property("st", "pushAnnotations"), Expressions.bool(true)));
7772 17 Feb 20 nicklas 107     }
6791 23 Mar 15 nicklas 108
6791 23 Mar 15 nicklas 109     // If we have collected downstream extracts we must
6791 23 Mar 15 nicklas 110     // ADD ALL parent extracts to those that were collected
6791 23 Mar 15 nicklas 111     // REMOVE ALL extracts that are not found among the children to the collected extracts
6791 23 Mar 15 nicklas 112     Set<Integer> upstream = null;
6791 23 Mar 15 nicklas 113     Set<Integer> downstream = null;    
7836 28 Aug 20 nicklas 114     if (collectedExtracts != null && collectedExtracts.getCollected().size() > 0)
6791 23 Mar 15 nicklas 115     {
6791 23 Mar 15 nicklas 116       // The 'upstream' is all collected extracts and their parents
6801 25 Mar 15 nicklas 117       upstream = collectedExtracts.getCollectedParents();
6791 23 Mar 15 nicklas 118       // The 'downstream' is all collected and their children
6801 25 Mar 15 nicklas 119       downstream = collectedExtracts.getCollectedChildren();
6791 23 Mar 15 nicklas 120
6791 23 Mar 15 nicklas 121       // We remove all upstream since those are already loaded
6791 23 Mar 15 nicklas 122       // and only keep those that are found downstream
6791 23 Mar 15 nicklas 123       source = new HashSet<Integer>(source);
6791 23 Mar 15 nicklas 124       source.removeAll(upstream);
6791 23 Mar 15 nicklas 125       source.retainAll(downstream);
6791 23 Mar 15 nicklas 126     }
6775 17 Mar 15 nicklas 127     
6775 17 Mar 15 nicklas 128     // Keep track of all seen children and parents
6775 17 Mar 15 nicklas 129     Set<Integer> allParents = new HashSet<Integer>();
6775 17 Mar 15 nicklas 130     Set<Integer> allChildren = new HashSet<Integer>();
6775 17 Mar 15 nicklas 131     if (includeSourcesInTarget) allParents.addAll(source);
6775 17 Mar 15 nicklas 132
6775 17 Mar 15 nicklas 133     // Children that we have not yet checked
6775 17 Mar 15 nicklas 134     Set<Integer> children = source;
6791 23 Mar 15 nicklas 135     
6775 17 Mar 15 nicklas 136     while (children.size() > 0)
6775 17 Mar 15 nicklas 137     {
8094 04 Nov 22 nicklas 138       context.collect(getSourceItemType(), children);
8094 04 Nov 22 nicklas 139       Set<Integer> parents = context.avoid(getTargetItemType(), safeIdList(dc, query, "children", children));
6791 23 Mar 15 nicklas 140       if (upstream != null) parents.removeAll(upstream);
6791 23 Mar 15 nicklas 141       if (downstream != null) parents.retainAll(downstream);
6791 23 Mar 15 nicklas 142       
6775 17 Mar 15 nicklas 143       // Store new parents and "used" children
6775 17 Mar 15 nicklas 144       allParents.addAll(parents);
6775 17 Mar 15 nicklas 145       allChildren.addAll(children);
6775 17 Mar 15 nicklas 146       
6775 17 Mar 15 nicklas 147       // Remove children that we have already seen...
6775 17 Mar 15 nicklas 148       // ...the remaining parents become our new children
6775 17 Mar 15 nicklas 149       parents.removeAll(allChildren);
6775 17 Mar 15 nicklas 150       children = parents;
6775 17 Mar 15 nicklas 151     }
6775 17 Mar 15 nicklas 152     
6791 23 Mar 15 nicklas 153     // Finally add all upstream parent extracts
6791 23 Mar 15 nicklas 154     if (upstream != null) allParents.addAll(upstream);
6791 23 Mar 15 nicklas 155     
6775 17 Mar 15 nicklas 156     return allParents;
6775 17 Mar 15 nicklas 157   }
6775 17 Mar 15 nicklas 158
6775 17 Mar 15 nicklas 159
6775 17 Mar 15 nicklas 160 }