Changeset 8094
- Timestamp:
- Nov 4, 2022, 9:05:30 AM (5 months ago)
- Location:
- trunk
- Files:
-
- 38 edited
- 3 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/3.19-stable merged: 8082,8084-8091 /tags/3.19.5 (added) merged: 8092
- Property svn:mergeinfo changed
-
trunk/.classpath
r7994 r8094 35 35 <classpathentry kind="lib" path="lib/dist/poi-ooxml-5.0.0.jar"/> 36 36 <classpathentry kind="lib" path="lib/dist/hibernate-core-5.5.6.Final.jar"/> 37 <classpathentry kind="lib" path="lib/dist/zip4j-2.11.2.jar"/> 37 38 <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"> 38 39 <attributes> -
trunk/doc/3rd-party-components.txt
r7994 r8094 303 303 Files : AffxFusion.jar 304 304 305 ZIP file support 306 ---------------- 307 A library for reading and writing ZIP files. 308 309 More info: https://github.com/srikanth-lingala/zip4j 310 Version : 2.11.2 311 License : zip4j-license.txt 312 Files : zip4j-2.11.2.jar 313 314 305 315 TAR file support 306 316 ---------------- … … 382 392 commons-compress-1.20.jar, commons-math3-3.6.1.jar, xmlbeans-4.0.0.jar 383 393 394 -
trunk/doc/src/docbook/user/webclient.xml
r8083 r8094 2410 2410 </listitem> 2411 2411 </varlistentry> 2412 2413 <varlistentry> 2414 <term><guilabel>Allow doubling back</guilabel></term> 2415 <listitem> 2416 <para> 2417 The normal operation when both a parent and child selection 2418 has been made is that the path used when going up to the parent 2419 is ignored when going down to the child. If this option is checked 2420 then it is allowed to "double back" the same path also when going 2421 down to the child item. 2422 </para> 2423 </listitem> 2424 </varlistentry> 2412 2425 2413 2426 <varlistentry> -
trunk/src/clients/web/net/sf/basedb/clients/web/extensions/list/RelatedItemColumn.java
r8083 r8094 146 146 if (dc != null) 147 147 { 148 SourceItemTransformerFactory transformerFactory = ListableUtil.getTransformerFactory(spec.targetType); 148 boolean includeChildrenThatPushToParents = !spec.multiHop && 149 (spec.getTargetType() == Item.EXTRACT || spec.getTargetType() == Item.SAMPLE) && 150 spec.getItemSubtype(dc).getPushAnnotations(); 151 SourceItemTransformerFactory transformerFactory = ListableUtil.getTransformerFactory(spec.targetType, includeChildrenThatPushToParents); 149 152 SourceItemTransformer tmp = transformerFactory.create(spec.sourceType, spec.direction); 150 153 Restriction targetRestriction = spec.createTargetTypeRestriction(dc); … … 186 189 187 190 /** 191 Get the specification for this column. 192 @since 3.19.5 193 */ 194 protected Specification getSpecification() 195 { 196 return spec; 197 } 198 199 /** 188 200 We finalize this implementation to make sure that the helper 189 201 implementation always get a chance to re-cycle transactions. … … 258 270 { 259 271 Set<Integer> sourceIds = Collections.singleton(item.getId()); 272 helper.transformContext.resetCollected(); 260 273 if (preTransform != null) 261 274 { 275 if (!spec.allowDoublingBack) helper.transformContext.setCollecting(); 262 276 sourceIds = preTransform.transform(helper.transformContext, sourceIds); 277 if (!spec.allowDoublingBack) helper.transformContext.setAvoiding(); 263 278 } 264 279 Set<Integer> relatedIds = transformer.transform(helper.transformContext, sourceIds); … … 306 321 baseIndex = 2; 307 322 spec.directionRaw = tmp[1]; 308 if ("CHILD".equals(spec.directionRaw)) spec.direction = SourceItemTransform.PARENT_TO_CHILD; 323 if (spec.directionRaw.endsWith("+")) spec.allowDoublingBack = true; 324 if (spec.directionRaw.startsWith("CHILD")) spec.direction = SourceItemTransform.PARENT_TO_CHILD; 309 325 } 310 326 spec.targetType = Item.valueOf(tmp[baseIndex]); … … 350 366 String directionRaw; 351 367 SourceItemTransform direction; 368 boolean allowDoublingBack; 352 369 Item sourceType; 353 370 Item targetType; … … 385 402 386 403 /** 404 Enabled on a multi-hop path if the path down to the related child from the 405 parent item is allowed to traverse the same items as the path up from 406 the source child item to the parent. 407 */ 408 public boolean isDoublingBackAllowed() 409 { 410 return allowDoublingBack; 411 } 412 413 /** 387 414 Get the source item type. This is not part of the expression, but 388 415 is taken from the current list. … … 471 498 result += direction == SourceItemTransform.CHILD_TO_PARENT ? "parentitem" : "childitem"; 472 499 if (multiHop) result += " multihop"; 500 if (allowDoublingBack) result += " doublingback"; 473 501 result += "\">"; 474 502 result += StringUtil.coalesce(subtypeName, targetType.name()); -
trunk/src/clients/web/net/sf/basedb/clients/web/extensions/list/RelatedItemMultiHopColumn.java
r8083 r8094 18 18 19 19 private final RelatedItemColumn nextHop; 20 private final Specification nextSpec; 21 20 22 RelatedItemMultiHopColumn(DbControl dc, int index, Specification spec, RelatedItemHelper helper, RelatedItemColumn nextHop) 21 23 { 22 24 super(dc, index, spec, helper); 23 25 this.nextHop = nextHop; 26 this.nextSpec = nextHop.getSpecification(); 24 27 25 28 setValueType(nextHop.getValueType()); … … 43 46 setTitle(spec.generateTitle(nextHop.getTitle())); 44 47 setSubtitle(nextHop.getSubtitle()); 45 setTooltip(spec.generateTooltip(StringUtil.coalesce(nextHop.getTooltip(), nextHop.getTitle()))); 48 setTooltip(spec.generateTooltip(StringUtil.coalesce(nextHop.getTooltip(), nextHop.getTitle())+ 49 (nextSpec.allowDoublingBack ? " (doubling back allowed)" : " (no doubling back)"))); 46 50 } 47 51 -
trunk/src/core/net/sf/basedb/core/PropertyFilter.java
r8083 r8094 120 120 private Unit unit; 121 121 private boolean temporary; 122 private TransformContext transformContext; 122 123 123 124 /** … … 866 867 String[] parts = property.split("/", 5); 867 868 SourceItemTransform direction = SourceItemTransform.PARENT_TO_CHILD; 869 boolean allowDoublingBack = false; 868 870 int baseIndex = 1; 869 871 if (parts.length == 5) // The /DIRECTION is optional 870 872 { 871 873 baseIndex = 2; 872 direction = "CHILD".equals(parts[1]) ? SourceItemTransform.CHILD_TO_PARENT : SourceItemTransform.PARENT_TO_CHILD; 874 if (parts[1].startsWith("CHILD")) direction = SourceItemTransform.CHILD_TO_PARENT; 875 allowDoublingBack = parts[1].endsWith("+"); 873 876 } 874 877 Item targetType = Item.valueOf(parts[baseIndex]); … … 896 899 } 897 900 PropertyFilter pp = new PropertyFilter(targetProperty, operator, getValue(), getValueType()); 901 // Create a TransformContext unless we already have one 902 // The subquery must use the same TransformContext in case we need the "doubling back" feature 903 TransformContext tCtx = transformContext == null ? new TransformContext(dc) : transformContext; 904 pp.transformContext = tCtx; 898 905 ClientContext subContext = new ClientContext(dc); 899 906 if (context != null) subContext.linkAttributes(context); … … 907 914 cc.setException(targetItemContext.getException()); 908 915 } 909 916 910 917 // We then transform the list if ID:s to a list of child item ID:s using ItemList functionality 911 918 SortedSet<Integer> parentIds = new TreeSet<>(subquery.idList(dc)); 912 TransformContext tCtx = new TransformContext(dc);913 919 914 920 SourceItemTransformerFactory factory = ListableUtil.getTransformerFactory(query.getItemType()); 915 factory = new SourceItemTransformerWithCache(factory); 921 factory = new SourceItemTransformerWithCache(factory, tCtx.isAvoiding() ? property+operator+value : null); 922 // If we are in a subquery the main query may need this for the "doubling back" feature 923 if (transformContext != null && !allowDoublingBack) transformContext.setCollecting(); 916 924 Set<Integer> myIds = factory.create(targetType, direction).transform(tCtx, parentIds); 925 // If we are in a subquery the main query may need this for the "doubling back" feature 926 if (transformContext != null && !allowDoublingBack) transformContext.setAvoiding(); 917 927 918 928 // The final ID list is returned as a restriction -
trunk/src/core/net/sf/basedb/util/listable/BioSourceToSampleTransformer.java
r6848 r8094 56 56 public Set<Integer> transform(TransformContext context, Set<Integer> source) 57 57 { 58 context.collect(getSourceItemType(), source); 58 59 ItemQuery<Sample> query = Sample.getQuery(); 59 60 query.setIncludes(context.getInclude()); … … 65 66 Expressions.parameter("biosources") 66 67 )); 67 return safeIdList(context.getDbControl(), query, "biosources", source);68 return context.avoid(getTargetItemType(), safeIdList(context.getDbControl(), query, "biosources", source)); 68 69 } 69 70 -
trunk/src/core/net/sf/basedb/util/listable/DerivedBioAssayToChildDerivedBioAssayTransformer.java
r6848 r8094 79 79 while (parents.size() > 0) 80 80 { 81 Set<Integer> children = safeIdList(dc, query, "parents", parents); 81 context.collect(getSourceItemType(), parents); 82 Set<Integer> children = context.avoid(getTargetItemType(), safeIdList(dc, query, "parents", parents)); 82 83 83 84 // Store new children and "used" parents -
trunk/src/core/net/sf/basedb/util/listable/DerivedBioAssayToParentDerivedBioAssayTransformer.java
r6848 r8094 79 79 while (children.size() > 0) 80 80 { 81 Set<Integer> parents = safeIdList(dc, query, "children", children); 81 context.collect(getSourceItemType(), children); 82 Set<Integer> parents = context.avoid(getTargetItemType(), safeIdList(dc, query, "children", children)); 82 83 83 84 // Store new parents and "used" children -
trunk/src/core/net/sf/basedb/util/listable/DerivedBioAssayToPhysicalBioAssayTransformer.java
r6848 r8094 24 24 import java.util.Set; 25 25 26 import net.sf.basedb.core.DbControl;27 26 import net.sf.basedb.core.Item; 28 27 import net.sf.basedb.core.ItemQuery; … … 54 53 public Set<Integer> transform(TransformContext context, Set<Integer> source) 55 54 { 56 DbControl dc = context.getDbControl(); 57 55 context.collect(getSourceItemType(), source); 58 56 ItemQuery<PhysicalBioAssay> query = PhysicalBioAssay.getQuery(); 59 57 query.setIncludes(context.getInclude()); … … 66 64 ); 67 65 68 return safeIdList(context.getDbControl(), query, "bioAssays", source);66 return context.avoid(getTargetItemType(), safeIdList(context.getDbControl(), query, "bioAssays", source)); 69 67 } 70 68 -
trunk/src/core/net/sf/basedb/util/listable/DerivedBioAssayToRawBioAssayTransformer.java
r6848 r8094 67 67 public Set<Integer> transform(TransformContext context, Set<Integer> source) 68 68 { 69 context.collect(getSourceItemType(), source); 69 70 DbControl dc = context.getDbControl(); 70 71 … … 78 79 ) 79 80 ); 80 Set<Integer> all = safeIdList(dc, query, "bioAssays", source);81 Set<Integer> all = context.avoid(getTargetItemType(), safeIdList(dc, query, "bioAssays", source)); 81 82 82 83 if (collectedExtracts != null) -
trunk/src/core/net/sf/basedb/util/listable/ExtractToChildExtractTransformer.java
r6848 r8094 47 47 48 48 private final boolean includeSourcesInTarget; 49 private final boolean pushOnly; 49 50 50 51 /** … … 54 55 public ExtractToChildExtractTransformer(boolean includeSourcesInTarget) 55 56 { 57 this(includeSourcesInTarget, false); 58 } 59 /** 60 Create a new extract to child extract transformer that only load children 61 has a subtype with "push annotations" set. 62 @since 3.19.5 63 */ 64 public ExtractToChildExtractTransformer(boolean includeSourcesInTarget, boolean childrensThatPushOnly) 65 { 56 66 super(Item.EXTRACT, Item.EXTRACT); 57 67 this.includeSourcesInTarget = includeSourcesInTarget; 68 this.pushOnly = childrensThatPushOnly; 58 69 } 59 70 60 71 @Override 61 72 public Set<Integer> transform(TransformContext context, Set<Integer> source) … … 75 86 Expressions.parameter("parents") 76 87 )); 88 if (pushOnly) 89 { 90 query.join(Hql.innerJoin("itemSubtype", "st")); 91 query.restrict(Restrictions.eq(Hql.property("st", "pushAnnotations"), Expressions.bool(true))); 92 } 77 93 78 94 // Keep track of all seen children and parents … … 85 101 while (parents.size() > 0) 86 102 { 87 Set<Integer> children = safeIdList(dc, query, "parents", parents); 103 context.collect(getSourceItemType(), parents); 104 Set<Integer> children = context.avoid(getTargetItemType(), safeIdList(dc, query, "parents", parents)); 88 105 89 106 // Store new children and "used" parents -
trunk/src/core/net/sf/basedb/util/listable/ExtractToParentExtractTransformer.java
r7836 r8094 136 136 while (children.size() > 0) 137 137 { 138 Set<Integer> parents = safeIdList(dc, query, "children", children); 138 context.collect(getSourceItemType(), children); 139 Set<Integer> parents = context.avoid(getTargetItemType(), safeIdList(dc, query, "children", children)); 139 140 if (upstream != null) parents.removeAll(upstream); 140 141 if (downstream != null) parents.retainAll(downstream); -
trunk/src/core/net/sf/basedb/util/listable/ExtractToPhysicalBioAssayTransformer.java
r6848 r8094 24 24 import java.util.Set; 25 25 26 import net.sf.basedb.core.DbControl;27 26 import net.sf.basedb.core.Item; 28 27 import net.sf.basedb.core.ItemQuery; … … 53 52 public Set<Integer> transform(TransformContext context, Set<Integer> source) 54 53 { 55 DbControl dc = context.getDbControl(); 56 54 context.collect(getSourceItemType(), source); 57 55 ItemQuery<PhysicalBioAssay> query = PhysicalBioAssay.getQuery(); 58 56 query.setIncludes(context.getInclude()); … … 65 63 Expressions.parameter("parents") 66 64 )); 67 return safeIdList(context.getDbControl(), query, "parents", source);65 return context.avoid(getTargetItemType(), safeIdList(context.getDbControl(), query, "parents", source)); 68 66 } 69 67 -
trunk/src/core/net/sf/basedb/util/listable/ExtractToSampleTransformer.java
r7772 r8094 74 74 public Set<Integer> transform(TransformContext context, Set<Integer> source) 75 75 { 76 context.collect(getSourceItemType(), source); 76 77 ItemQuery<Sample> query = Sample.getQuery(); 77 78 query.setIncludes(context.getInclude()); … … 88 89 query.restrict(Restrictions.eq(Hql.property("st", "pushAnnotations"), Expressions.bool(true))); 89 90 } 90 return safeIdList(context.getDbControl(), query, "extracts", source);91 return context.avoid(getTargetItemType(), safeIdList(context.getDbControl(), query, "extracts", source)); 91 92 } 92 93 -
trunk/src/core/net/sf/basedb/util/listable/ListableUtil.java
r6787 r8094 27 27 28 28 import net.sf.basedb.core.Item; 29 import net.sf.basedb.core.ItemSubtype; 29 30 import net.sf.basedb.core.Listable; 30 31 import net.sf.basedb.core.SyncFilter.SourceItemTransform; … … 66 67 public static SourceItemTransformerFactory getTransformerFactory(Item targetItemType) 67 68 { 69 return getTransformerFactory(targetItemType, false); 70 } 71 72 /** 73 Create a source item transformer factory that can transform items to the given 74 target item type. If no transformer factory exists, null is returned. 75 The 'includeChildrenThatPushToParent' parameter can be used for transforms 76 that go from child to parent items, when the target is a SAMPLE or EXTRACT. 77 When this flag is set, transformer will also include child items that have 78 a subtype that have the {@link ItemSubtype#getPushAnnotations()} flag enabled 79 in the final result. 80 81 @since 3.19.5 82 */ 83 public static SourceItemTransformerFactory getTransformerFactory(Item targetItemType, boolean includeChildrenThatPushToParent) 84 { 68 85 SourceItemTransformerFactory factory = null; 69 86 if (targetItemType == Item.BIOSOURCE) … … 73 90 else if (targetItemType == Item.SAMPLE) 74 91 { 75 factory = new ToSampleSourceItemTransformerFactory( );92 factory = new ToSampleSourceItemTransformerFactory(includeChildrenThatPushToParent); 76 93 } 77 94 else if (targetItemType == Item.EXTRACT) 78 95 { 79 factory = new ToExtractSourceItemTransformerFactory( );96 factory = new ToExtractSourceItemTransformerFactory(includeChildrenThatPushToParent); 80 97 } 81 98 else if (targetItemType == Item.PHYSICALBIOASSAY) -
trunk/src/core/net/sf/basedb/util/listable/PhysicalBioAssayToDerivedBioAssayTransformer.java
r6848 r8094 80 80 ) 81 81 ); 82 Set<Integer> all = safeIdList(dc, query, "bioAssays", source); 82 context.collect(getSourceItemType(), source); 83 Set<Integer> all = context.avoid(getTargetItemType(), safeIdList(dc, query, "bioAssays", source)); 83 84 84 85 if (collectedExtracts != null) -
trunk/src/core/net/sf/basedb/util/listable/PhysicalBioAssayToExtractTransformer.java
r6848 r8094 55 55 public Set<Integer> transform(TransformContext context, Set<Integer> source) 56 56 { 57 context.collect(getSourceItemType(), source); 57 58 ItemQuery<Extract> query = Extract.getQuery(); 58 59 query.setIncludes(context.getInclude()); … … 66 67 ) 67 68 ); 68 return safeIdList(context.getDbControl(), query, "bioAssays", source);69 return context.avoid(getTargetItemType(), safeIdList(context.getDbControl(), query, "bioAssays", source)); 69 70 } 70 71 -
trunk/src/core/net/sf/basedb/util/listable/RawBioAssayToDerivedBioAssayTransformer.java
r6848 r8094 24 24 import java.util.Set; 25 25 26 import net.sf.basedb.core.DbControl;27 26 import net.sf.basedb.core.DerivedBioAssay; 28 27 import net.sf.basedb.core.Item; … … 55 54 public Set<Integer> transform(TransformContext context, Set<Integer> source) 56 55 { 57 DbControl dc = context.getDbControl(); 58 56 context.collect(getSourceItemType(), source); 59 57 ItemQuery<DerivedBioAssay> query = DerivedBioAssay.getQuery(); 60 58 query.setIncludes(context.getInclude()); … … 66 64 ) 67 65 ); 68 return safeIdList(context.getDbControl(), query, "rawBioAssays", source);66 return context.avoid(getTargetItemType(), safeIdList(context.getDbControl(), query, "rawBioAssays", source)); 69 67 } 70 68 -
trunk/src/core/net/sf/basedb/util/listable/SampleToBioSourceTransformer.java
r7772 r8094 71 71 public Set<Integer> transform(TransformContext context, Set<Integer> source) 72 72 { 73 context.collect(getSourceItemType(), source); 73 74 ItemQuery<BioSource> query = BioSource.getQuery(); 74 75 query.setIncludes(context.getInclude()); … … 85 86 query.restrict(Restrictions.eq(Hql.property("st", "pushAnnotations"), Expressions.bool(true))); 86 87 } 87 return safeIdList(context.getDbControl(), query, "samples", source);88 return context.avoid(getTargetItemType(), safeIdList(context.getDbControl(), query, "samples", source)); 88 89 } 89 90 -
trunk/src/core/net/sf/basedb/util/listable/SampleToChildSampleTransformer.java
r6848 r8094 29 29 import net.sf.basedb.core.ItemQuery; 30 30 import net.sf.basedb.core.Sample; 31 import net.sf.basedb.core.Type;32 31 import net.sf.basedb.core.query.Expressions; 33 32 import net.sf.basedb.core.query.Hql; … … 48 47 49 48 private final boolean includeSourcesInTarget; 49 private final boolean pushOnly; 50 50 51 51 /** … … 55 55 public SampleToChildSampleTransformer(boolean includeSourcesInTarget) 56 56 { 57 this(includeSourcesInTarget, false); 58 } 59 /** 60 Create a new sample to child sample transformer that only load children that 61 has a subtype with "push annotations" set. 62 @since 3.19.5 63 */ 64 public SampleToChildSampleTransformer(boolean includeSourcesInTarget, boolean childrensThatPushOnly) 65 { 57 66 super(Item.SAMPLE, Item.SAMPLE); 58 67 this.includeSourcesInTarget = includeSourcesInTarget; 68 this.pushOnly = childrensThatPushOnly; 59 69 } 60 70 61 71 @Override 62 72 public Set<Integer> transform(TransformContext context, Set<Integer> source) … … 76 86 Expressions.parameter("parents") 77 87 )); 88 if (pushOnly) 89 { 90 query.join(Hql.innerJoin("itemSubtype", "st")); 91 query.restrict(Restrictions.eq(Hql.property("st", "pushAnnotations"), Expressions.bool(true))); 92 } 78 93 79 94 // Keep track of all seen children and parents … … 86 101 while (parents.size() > 0) 87 102 { 88 query.setParameter("parents", parents, Type.INT);89 Set<Integer> children = safeIdList(dc, query, "parents", parents);103 context.collect(getSourceItemType(), parents); 104 Set<Integer> children = context.avoid(getTargetItemType(), safeIdList(dc, query, "parents", parents)); 90 105 91 106 // Store new children and "used" parents -
trunk/src/core/net/sf/basedb/util/listable/SampleToExtractTransformer.java
r6848 r8094 57 57 public Set<Integer> transform(TransformContext context, Set<Integer> source) 58 58 { 59 context.collect(getSourceItemType(), source); 59 60 ItemQuery<Extract> query = Extract.getQuery(); 60 61 query.setIncludes(context.getInclude()); … … 66 67 Expressions.parameter("samples") 67 68 )); 68 return safeIdList(context.getDbControl(), query, "samples", source);69 return context.avoid(getTargetItemType(), safeIdList(context.getDbControl(), query, "samples", source)); 69 70 } 70 71 -
trunk/src/core/net/sf/basedb/util/listable/SampleToParentSampleTransformer.java
r7772 r8094 103 103 while (children.size() > 0) 104 104 { 105 Set<Integer> parents = safeIdList(dc, query, "children", children); 105 context.collect(getSourceItemType(), children); 106 Set<Integer> parents = context.avoid(getTargetItemType(), safeIdList(dc, query, "children", children)); 106 107 107 108 // Store new parents and "used" children -
trunk/src/core/net/sf/basedb/util/listable/SourceItemTransformerChain.java
r6801 r8094 102 102 for (SourceItemTransformer sit : chain) 103 103 { 104 //System.out.println(sit + " before: " + sit.getSourceItemType() + "=" + source.size() +":" + source);105 104 source = sit.transform(context, source); 106 //System.out.println("After: " + sit.getTargetItemType() + "=" + source.size());107 105 } 108 106 return source; -
trunk/src/core/net/sf/basedb/util/listable/SourceItemTransformerWithCache.java
r7772 r8094 47 47 48 48 private final SourceItemTransformerFactory factory; 49 private final String cacheRegion; 49 50 50 51 /** … … 57 58 public SourceItemTransformerWithCache(SourceItemTransformerFactory factory) 58 59 { 59 this .factory = factory;60 this(factory, null); 60 61 } 61 62 63 public SourceItemTransformerWithCache(SourceItemTransformerFactory factory, String cacheRegion) 64 { 65 this.factory = factory; 66 this.cacheRegion = cacheRegion; 67 } 68 69 62 70 @Override 63 71 public Item getTargetItem() … … 75 83 public SourceItemTransformer create(Item sourceItemType, SourceItemTransform transform) 76 84 { 77 return new TransformerWithCache(factory.create(sourceItemType, transform), transform );85 return new TransformerWithCache(factory.create(sourceItemType, transform), transform, cacheRegion); 78 86 } 79 87 … … 85 93 private final SourceItemTransformer transformer; 86 94 private final SourceItemTransform transform; 95 private final String cacheRegion; 87 96 88 TransformerWithCache(SourceItemTransformer transformer, SourceItemTransform transform )97 TransformerWithCache(SourceItemTransformer transformer, SourceItemTransform transform, String cacheRegion) 89 98 { 90 99 this.transformer = transformer; 91 100 this.transform = transform; 101 this.cacheRegion = cacheRegion; 92 102 } 93 103 … … 117 127 if (cache != null) 118 128 { 119 key = TransformCache.getKey( getSourceItemType(), getTargetItemType(), transform, source);129 key = TransformCache.getKey(cacheRegion, getSourceItemType(), getTargetItemType(), transform, source); 120 130 target = cache.get(key); 121 131 } -
trunk/src/core/net/sf/basedb/util/listable/ToBioSourceSourceItemTransformerFactory.java
r6791 r8094 68 68 69 69 // Use utility function to add transformation up to the extract level 70 ToExtractSourceItemTransformerFactory.childToParentChain(chain, sourceItemType, Item.BIOSOURCE );70 ToExtractSourceItemTransformerFactory.childToParentChain(chain, sourceItemType, Item.BIOSOURCE, false); 71 71 if (chain.size() > 0) 72 72 { -
trunk/src/core/net/sf/basedb/util/listable/ToExtractSourceItemTransformerFactory.java
r7772 r8094 50 50 { Item.EXTRACT, Item.PHYSICALBIOASSAY, Item.DERIVEDBIOASSAY, Item.RAWBIOASSAY }; 51 51 52 private final boolean includeChildrenThatPushToParent; 52 53 53 54 public ToExtractSourceItemTransformerFactory() 54 55 { 56 this(false); 57 } 58 59 public ToExtractSourceItemTransformerFactory(boolean includeChildrenThatPushToParent) 60 { 55 61 super(Item.EXTRACT, PARENT_TO_CHILD, CHILD_TO_PARENT); 62 this.includeChildrenThatPushToParent = includeChildrenThatPushToParent; 56 63 } 57 64 … … 93 100 else if (transform == SourceItemTransform.CHILD_TO_PARENT) 94 101 { 95 childToParentChain(chain, sourceItemType, Item.EXTRACT );102 childToParentChain(chain, sourceItemType, Item.EXTRACT, includeChildrenThatPushToParent); 96 103 } 97 104 … … 105 112 DERIVEDBIOASSAY, PHYSICALBIOASSAY and EXTRACT 106 113 */ 107 static void childToParentChain(List<SourceItemTransformer> chain, Item sourceItemType, Item targetItemType )114 static void childToParentChain(List<SourceItemTransformer> chain, Item sourceItemType, Item targetItemType, boolean includeChildrenThatPushToParent) 108 115 { 109 116 Item stepBySource = null; … … 146 153 // Load parent extracts, maybe including the source extracts 147 154 chain.add(new ExtractToParentExtractTransformer(sourceItemType != targetItemType, collectedExtracts)); 155 // Also include child extracts that have push-to-parent flag set 156 if (includeChildrenThatPushToParent && targetItemType == Item.EXTRACT) 157 { 158 chain.add(new ExtractToChildExtractTransformer(true, true)); 159 } 148 160 } 149 161 -
trunk/src/core/net/sf/basedb/util/listable/ToSampleSourceItemTransformerFactory.java
r7772 r8094 51 51 52 52 53 private final boolean includeChildrenThatPushToParent; 54 53 55 public ToSampleSourceItemTransformerFactory() 54 56 { 55 super(Item.SAMPLE, PARENT_TO_CHILD, CHILD_TO_PARENT);57 this(false); 56 58 } 57 59 58 60 public ToSampleSourceItemTransformerFactory(boolean includeChildrenThatPushToParent) 61 { 62 super(Item.SAMPLE, PARENT_TO_CHILD, CHILD_TO_PARENT); 63 this.includeChildrenThatPushToParent = includeChildrenThatPushToParent; 64 } 65 59 66 @Override 60 67 public SourceItemTransformer create(final Item sourceItemType, final SourceItemTransform transform) … … 87 94 88 95 // Use utility function to add transformation up to the extract level 89 ToExtractSourceItemTransformerFactory.childToParentChain(chain, sourceItemType, Item.SAMPLE );96 ToExtractSourceItemTransformerFactory.childToParentChain(chain, sourceItemType, Item.SAMPLE, false); 90 97 if (chain.size() > 0) 91 98 { … … 99 106 // Load parent samples and maybe include source samples 100 107 chain.add(new SampleToParentSampleTransformer(sourceItemType != Item.SAMPLE)); 108 // Also include child samples that have push-to-parent flag set 109 if (includeChildrenThatPushToParent) 110 { 111 chain.add(new SampleToChildSampleTransformer(true, true)); 112 } 101 113 } 102 114 } -
trunk/src/core/net/sf/basedb/util/listable/TransformCache.java
r7770 r8094 30 30 public static CacheKey getKey(Item sourceType, Item targetType, SyncFilter.SourceItemTransform transform, Set<Integer> sourceIds) 31 31 { 32 return getKey(null, sourceType, targetType, transform, sourceIds); 33 } 34 35 public static CacheKey getKey(String cacheRegion, Item sourceType, Item targetType, SyncFilter.SourceItemTransform transform, Set<Integer> sourceIds) 36 { 32 37 SortedSet<Integer> sortedSrc = sourceIds instanceof SortedSet ? (SortedSet<Integer>)sourceIds : new TreeSet<>(sourceIds); 33 return new CacheKey( sourceType, targetType, transform, sortedSrc);38 return new CacheKey(cacheRegion, sourceType, targetType, transform, sortedSrc); 34 39 } 35 40 … … 96 101 public static class CacheKey 97 102 { 103 private final String cacheRegion; 98 104 private final Item sourceType; 99 105 private final Item targetType; … … 101 107 private final String sourceIdHash; 102 108 103 CacheKey( Item sourceType, Item targetType, SyncFilter.SourceItemTransform transform, SortedSet<Integer> sourceIds)109 CacheKey(String cacheRegion, Item sourceType, Item targetType, SyncFilter.SourceItemTransform transform, SortedSet<Integer> sourceIds) 104 110 { 111 this.cacheRegion = cacheRegion==null?"":cacheRegion; 105 112 this.sourceType = sourceType; 106 113 this.targetType = targetType; … … 112 119 public int hashCode() 113 120 { 114 return sourceType.hashCode() + 3 * targetType.hashCode() + 7 * transform.hashCode() + 11 * sourceIdHash.hashCode();121 return cacheRegion.hashCode()+sourceType.hashCode() + 3 * targetType.hashCode() + 7 * transform.hashCode() + 11 * sourceIdHash.hashCode(); 115 122 } 116 123 … … 120 127 if (!(obj instanceof CacheKey)) return false; 121 128 CacheKey other = (CacheKey)obj; 122 return sourceType == other.sourceType && targetType == other.targetType && 129 return cacheRegion.equals(other.cacheRegion) && 130 sourceType == other.sourceType && targetType == other.targetType && 123 131 transform == other.transform && sourceIdHash.equals(other.sourceIdHash); 124 132 } … … 127 135 public String toString() 128 136 { 129 return "CacheKey[" + sourceType.name() + "->" + targetType.name() + "; " + transform.name() + "; " + sourceIdHash + "]";130 } 137 return "CacheKey["+cacheRegion + ";" + sourceType.name() + "->" + targetType.name() + "; " + transform.name() + "; " + sourceIdHash + "]"; 138 } 131 139 } 132 140 -
trunk/src/core/net/sf/basedb/util/listable/TransformContext.java
r7770 r8094 23 23 24 24 import java.util.Collection; 25 import java.util.HashMap; 26 import java.util.HashSet; 27 import java.util.Map; 28 import java.util.Set; 25 29 26 30 import net.sf.basedb.core.DbControl; 27 31 import net.sf.basedb.core.Include; 32 import net.sf.basedb.core.Item; 28 33 29 34 /** … … 89 94 } 90 95 96 private boolean collecting; 97 private boolean avoiding; 98 private Map<Item, Set<Integer>> collectedByItemType; 99 100 101 /** 102 Enable/disable collecting of all source items that the transformers in 103 this context are using. 104 @since 3.19.5 105 */ 106 public void setCollecting(boolean collecting) 107 { 108 this.collecting = collecting; 109 } 110 111 /** 112 Shortcut for enabling 'collecting' and disabling 'avoiding'. 113 @since 3.19.5 114 */ 115 public void setCollecting() 116 { 117 this.collecting = true; 118 this.avoiding = false; 119 } 120 121 public boolean isCollecting() 122 { 123 return collecting; 124 } 125 126 /** 127 Enable/disable avoiding of returning any source items that has 128 been previously collected. 129 @since 3.19.5 130 */ 131 public void setAvoiding(boolean avoiding) 132 { 133 this.avoiding = avoiding; 134 } 135 /** 136 Shortcut for enabling 'avoiding' and disabling 'collecting'. 137 @since 3.19.5 138 */ 139 public void setAvoiding() 140 { 141 this.collecting = false; 142 this.avoiding = true; 143 } 144 145 public boolean isAvoiding() 146 { 147 return avoiding; 148 } 149 150 /** 151 Clear all collected items and disable both 'collecting' and 152 'avoiding'. 153 @since 3.19.5 154 */ 155 public void resetCollected() 156 { 157 this.collecting = false; 158 this.avoiding = false; 159 if (collectedByItemType != null) collectedByItemType.clear(); 160 } 161 162 /** 163 Store collected items for later use if collecting has been enabled. 164 @return The source items 165 */ 166 public Set<Integer> collect(Item itemType, Set<Integer> source) 167 { 168 if (collecting && source.size() > 0) 169 { 170 if (collectedByItemType == null) collectedByItemType = new HashMap<>(); 171 Set<Integer> collected = collectedByItemType.get(itemType); 172 if (collected == null) 173 { 174 collected = new HashSet<>(); 175 collectedByItemType.put(itemType, collected); 176 } 177 collected.addAll(source); 178 } 179 return source; 180 } 181 182 /** 183 Avoid collected items by removing them from the source set. 184 Note that this method modified the source set directly. 185 @return The source set 186 */ 187 public Set<Integer> avoid(Item itemType, Set<Integer> source) 188 { 189 if (avoiding && source.size() > 0) 190 { 191 if (collectedByItemType != null && collectedByItemType.containsKey(itemType)) 192 { 193 Set<Integer> collected = collectedByItemType.get(itemType); 194 source.removeAll(collected); 195 } 196 } 197 return source; 198 } 199 91 200 } -
trunk/src/core/net/sf/basedb/util/zip/FilePacker.java
r7551 r8094 27 27 import java.io.InputStream; 28 28 import java.io.OutputStream; 29 30 import net.sf.basedb.core.PluginParameter; 31 import net.sf.basedb.core.StringParameterType; 29 32 30 33 /** … … 65 68 66 69 /** 70 Does the packer support encryption or not? 71 The default implementation return false. 72 @since 3.19.5 73 */ 74 public default boolean supportsEncryption() 75 { 76 return false; 77 } 78 79 /** 80 The default implementation return a parameter asking for a password. 81 The implementing class may create another parameter as long as it is 82 named "password". This method is only called if the implementation 83 supports encryption. 84 @since 3.19.5 85 */ 86 public default PluginParameter<String> getPasswordParameter() 87 { 88 PluginParameter<String> passwordParameter = new PluginParameter<String> 89 ( 90 "password", "Password", "Enter a password to encrypt the archive." , new StringParameterType() 91 ); 92 return passwordParameter; 93 } 94 95 /** 96 Set the password to use for encrypting the archive. This method 97 is only called if the implementation supports encryption and the 98 user has entered a password. 99 @since 3.19.5 100 */ 101 public default void setPassword(String password) 102 {} 103 104 /** 67 105 The output stream that the compressed files should be written to. 68 106 @param out The output stream to write to -
trunk/src/core/net/sf/basedb/util/zip/ZipFilePacker.java
r6127 r8094 23 23 package net.sf.basedb.util.zip; 24 24 25 import net.lingala.zip4j.io.outputstream.ZipOutputStream; 26 import net.lingala.zip4j.model.ZipParameters; 27 import net.lingala.zip4j.model.enums.AesKeyStrength; 28 import net.lingala.zip4j.model.enums.CompressionLevel; 29 import net.lingala.zip4j.model.enums.CompressionMethod; 30 import net.lingala.zip4j.model.enums.EncryptionMethod; 31 import net.sf.basedb.core.BaseException; 32 import net.sf.basedb.core.PluginParameter; 33 import net.sf.basedb.core.StringParameterType; 25 34 import net.sf.basedb.util.FileUtil; 26 35 … … 28 37 import java.io.InputStream; 29 38 import java.io.OutputStream; 30 import java.util.zip.ZipEntry;31 import java.util.zip.ZipOutputStream;32 39 33 40 /** … … 42 49 { 43 50 private ZipOutputStream zip; 51 private String password; 44 52 45 53 /** … … 78 86 } 79 87 /** 80 *Wrap the output stream in a {@link ZipOutputStream}.81 88 Wrap the output stream in a {@link ZipOutputStream}. 89 */ 82 90 @Override 83 91 public void setOutputStream(OutputStream out) 84 92 { 85 this.zip = new ZipOutputStream(out); 86 zip.setMethod(ZipOutputStream.DEFLATED); 93 try 94 { 95 this.zip = password == null ? new ZipOutputStream(out) : new ZipOutputStream(out, password.toCharArray()); 96 } 97 catch (IOException ex) 98 { 99 throw new BaseException(ex); 100 } 87 101 } 102 88 103 /** 89 Create a new {@link ZipEntry} and write the compressed 90 data to it. 104 Encryption is supported. 105 @since 3.19.5 106 */ 107 @Override 108 public boolean supportsEncryption() 109 { 110 return true; 111 } 112 113 /** 114 Get the encyption password parameter. 115 @since 3.19.5 116 */ 117 @Override 118 public PluginParameter<String> getPasswordParameter() 119 { 120 PluginParameter<String> passwordParameter = new PluginParameter<String> 121 ( 122 "password", "Password", "Enter a password to encrypt the archive with strong AES256 encryption. " 123 + "If empty, the ZIP archive will not be encrypted." , new StringParameterType() 124 ); 125 return passwordParameter; 126 } 127 128 /** 129 @since 3.19.5 130 */ 131 @Override 132 public void setPassword(String password) 133 { 134 this.password = password; 135 } 136 137 /** 138 Create a new entry and write the compressed data to it. 91 139 */ 92 140 @Override … … 96 144 boolean isDirectory = in == null; 97 145 if (isDirectory && !entryName.endsWith("/")) entryName += "/"; 98 ZipEntry entry = new ZipEntry(entryName); 99 if (lastModified > 0) entry.setTime(lastModified); 100 if (isDirectory) 146 147 ZipParameters zipParameters = new ZipParameters(); 148 zipParameters.setFileNameInZip(entryName); 149 if (lastModified > 0) 101 150 { 102 entry.setMethod(ZipOutputStream.STORED); 103 entry.setSize(0); 104 entry.setCrc(0); 151 zipParameters.setLastModifiedFileTime(lastModified); 152 } 153 if (isDirectory) 154 { 155 zipParameters.setCompressionMethod(CompressionMethod.STORE); 156 zipParameters.setEntrySize(0); 157 zipParameters.setEntryCRC(0); 105 158 } 106 159 else 107 160 { 108 entry.setSize(size); 161 zipParameters.setCompressionMethod(CompressionMethod.DEFLATE); 162 zipParameters.setCompressionLevel(CompressionLevel.NORMAL); 163 zipParameters.setEntrySize(size); 164 if (password != null) 165 { 166 zipParameters.setEncryptFiles(true); 167 zipParameters.setEncryptionMethod(EncryptionMethod.AES); 168 zipParameters.setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_256); 169 } 109 170 } 110 zip.putNextEntry( entry);171 zip.putNextEntry(zipParameters); 111 172 if (!isDirectory) FileUtil.copy(in, zip); 112 173 zip.flush(); -
trunk/src/plugins/core/net/sf/basedb/plugins/PackedFileExporter.java
r7605 r8094 308 308 309 309 // Other options 310 if (packer.supportsEncryption()) 311 { 312 storeValue(job, request, ri.getParameter("password")); 313 } 310 314 storeValue(job, request, ri.getParameter("removeItems")); 311 315 if (saveAs != null) … … 358 362 List<Integer> directories = job.getValues("directories"); 359 363 boolean removeItems = Boolean.TRUE.equals(job.getValue("removeItems")); 364 String password = job.getValue("password"); 360 365 FilePacker packer = getPacker(); 366 if (packer.supportsEncryption() && password != null) 367 { 368 packer.setPassword(password); 369 } 361 370 362 371 ChainedProgressReporter chained = null; … … 528 537 parameters.add(getSaveAsParameter(null, null, defaultPath, requireFile)); 529 538 parameters.add(getOverwriteParameter(null, null)); 539 // Encryption 540 if (packer.supportsEncryption()) 541 { 542 parameters.add(packer.getPasswordParameter()); 543 } 530 544 531 545 // Remove parameter -
trunk/www/common/columns/add_relateditem_column.js
r8083 r8094 109 109 configure.clearList('childItemType'); 110 110 configure.clearList('childSubtype'); 111 Doc.element('allowDoublingBack').disabled = true; 111 112 112 113 var frm = document.forms['relatedItems']; … … 200 201 configure.clearColumns(); 201 202 configure.clearList('childSubtype'); 203 Doc.element('allowDoublingBack').disabled = true; 202 204 203 205 var frm = document.forms['relatedItems']; … … 267 269 frm.childSubtype.selectedIndex = 0; 268 270 frm.childSubtype.disabled = currentChildSubtypes.length == 0; 271 frm.allowDoublingBack.disabled = currentChildSubtypes.length == 0; 269 272 } 270 273 … … 371 374 data.childItemType = frm.childItemType.value; 372 375 data.childSubtype = frm.childSubtype.value; 376 data.allowDoublingBack = frm.allowDoublingBack.checked?1:0; 373 377 374 378 if (!data.targetItemType) … … 396 400 { 397 401 data.childSubtypeName = frm.childSubtype[frm.childSubtype.selectedIndex].text; 398 propertyPrefix += '/CHILD/'+data.childItemType+'/'+data.childSubtype+'/';402 propertyPrefix += (data.allowDoublingBack?'/CHILD+/':'/CHILD/')+data.childItemType+'/'+data.childSubtype+'/'; 399 403 titlePrefix += '.'+data.childSubtypeName; 400 404 } -
trunk/www/common/columns/add_relateditem_column.jsp
r8083 r8094 58 58 { 59 59 width: 100%; 60 position: absolute; 61 border-collapse: separate; 62 } 63 64 .columnstable thead 65 { 66 position: sticky; 67 top: 0; 60 68 } 61 69 … … 63 71 { 64 72 vertical-align: top; 73 } 74 75 .columnstable tr.bottomborder th 76 { 77 border-bottom-width: 1px; 78 } 79 80 .columnstable tr.topborder th 81 { 82 border-top-width: 1px; 65 83 } 66 84 … … 170 188 </td> 171 189 </tr> 190 <tr> 191 <th class="subprompt"></th> 192 <td> 193 <label><input type="checkbox" id="showAllAnnotationTypes" 194 name="showAllAnnotationTypes">Show annotations for all subtypes</label> 195 </td> 196 <td></td> 197 <td> 198 <label title="Normally, child items that was passed when going up to the parent are ignored when going down. Enable this option to include all child items." 199 ><input type="checkbox" id="allowDoublingBack" name="allowDoublingBack" disabled 200 >Allow doubling back</label> 201 </td> 202 </tr> 172 203 <tr class="dynamic"> 173 204 <th></th> 174 <td ></td>175 <td></td>176 < td></td>205 <td colspan="3" class="columnsFrom" style="padding-top: 2px;"> 206 <span id="targetPath"></span><span id="childPath" class="childitem" style="display: none;"></span> 207 </td> 177 208 </tr> 178 209 </table> 179 210 </div> 180 211 181 <div class="absolutefull" style="top: 4em; left: 10em;"> 182 <div class="columnsFrom" style="height: 1.5em; white-space: nowrap; overflow: hidden;"> 183 <span id="targetPath"></span><span id="childPath" class="childitem" style="display: none;"></span> 184 <label style="font-weight: normal;"><input type="checkbox" id="showAllAnnotationTypes" 185 name="showAllAnnotationTypes">Show annotations for all subtypes</label> 186 </div> 212 <div class="absolutefull" style="top: 6.75em; left: 10em;"> 187 213 <table id="columnstable" class="columnstable" style="width: 100%;"> 188 <thead class=" bg-filled-100 topborder bottomborder">189 <tr >214 <thead class=""> 215 <tr class="bg-filled-100 topborder bottomborder"> 190 216 <th style="width: 33%;">Columns</th> 191 217 <th style="width: 33%;">Annotations</th> -
trunk/www/include/styles/table.css
r8083 r8094 253 253 } 254 254 255 /* A column header defining a parent/child item value */256 .itemlist div.data th.relateditemcol::before257 {258 margin-right: 2px;259 float: left;260 }261 262 255 .itemlist div.data th.relateditemcol span.parentitem::before 263 256 { … … 274 267 } 275 268 276 277 /* This will make room for the '›' without causing the header to wrap */ 278 .itemlist div.data th.relateditemcol > span 279 { 280 display: inline-block; 281 max-width: calc(100% - 16px); 282 overflow: hidden; 283 } 269 .itemlist div.data th.relateditemcol span.childitem.doublingback::before 270 { 271 content: url('../../images/child-item-doubleback.png'); 272 } 273 284 274 285 275 /* A column header defining a linked item value */
Note: See TracChangeset
for help on using the changeset viewer.