2121import org .jetbrains .annotations .NotNull ;
2222import org .jetbrains .annotations .Nullable ;
2323import org .labkey .api .collections .CaseInsensitiveHashMap ;
24+ import org .labkey .api .data .CompareType ;
2425import org .labkey .api .data .Container ;
2526import org .labkey .api .data .ContainerFilter ;
27+ import org .labkey .api .data .ContainerManager ;
2628import org .labkey .api .data .DbSchema ;
2729import org .labkey .api .data .DbScope ;
2830import org .labkey .api .data .JdbcType ;
31+ import org .labkey .api .data .Results ;
32+ import org .labkey .api .data .RuntimeSQLException ;
2933import org .labkey .api .data .SQLFragment ;
3034import org .labkey .api .data .SimpleFilter ;
3135import org .labkey .api .data .SqlExecutor ;
5054import org .labkey .api .reader .DataLoader ;
5155import org .labkey .api .reader .TabLoader ;
5256import org .labkey .api .security .User ;
57+ import org .labkey .api .security .permissions .Permission ;
5358import org .labkey .api .util .ContainerUtil ;
5459import org .labkey .api .util .FileUtil ;
5560import org .labkey .api .util .PageFlowUtil ;
61+ import org .labkey .api .view .UnauthorizedException ;
5662import org .labkey .microarray .controllers .FeatureAnnotationSetController ;
5763import org .labkey .microarray .matrix .ExpressionMatrixProtocolSchema ;
5864import org .labkey .microarray .query .MicroarrayUserSchema ;
5965
6066import java .io .File ;
6167import java .sql .SQLException ;
68+ import java .util .ArrayList ;
6269import java .util .Arrays ;
6370import java .util .Collection ;
6471import java .util .Collections ;
72+ import java .util .HashSet ;
6573import java .util .List ;
6674import java .util .Map ;
75+ import java .util .Set ;
76+
77+ import static org .labkey .api .data .DataRegion .MessagePart .filter ;
6778
6879public class MicroarrayManager
6980{
@@ -87,7 +98,7 @@ private static TableInfo getAnnotationQueryTableInfo(User user, Container contai
8798 return schema .getTable (MicroarrayUserSchema .TABLE_FEATURE_ANNOTATION , false );
8899 }
89100
90- private static TableInfo getAnnotationSetSchemaTableInfo ()
101+ public static TableInfo getAnnotationSetSchemaTableInfo ()
91102 {
92103 DbSchema schema = MicroarrayUserSchema .getSchema ();
93104 return schema .getTable (MicroarrayUserSchema .TABLE_FEATURE_ANNOTATION_SET );
@@ -105,32 +116,22 @@ public long featureAnnotationSetCount(Container c)
105116 return selector .getRowCount ();
106117 }
107118
108- public int deleteFeatureAnnotationSet (int ... rowId )
119+ public int deleteFeatureAnnotationSet (Collection < Integer > ids )
109120 {
110- DbScope scope = MicroarrayUserSchema .getSchema ().getScope ();
111-
112- Integer [] ids = ArrayUtils .toObject (rowId );
113-
114- try (DbScope .Transaction tx = scope .ensureTransaction ())
121+ try (DbScope .Transaction tx = MicroarrayUserSchema .getSchema ().getScope ().ensureTransaction ())
115122 {
116123 // Delete all annotations first.
117- TableInfo annotationSchemaTableInfo = getAnnotationSchemaTableInfo ();
118- SimpleFilter filter = new SimpleFilter ();
119- filter .addInClause (FieldKey .fromParts ("FeatureAnnotationSetId" ), Arrays .asList (ids ));
120- int rowsDeleted = Table .delete (annotationSchemaTableInfo , filter );
124+ int rowsDeleted = Table .delete (getAnnotationSchemaTableInfo (), new SimpleFilter (FieldKey .fromParts ("FeatureAnnotationSetId" ), ids , CompareType .IN ));
121125
122126 // Then delete annotation set.
123- TableInfo annotationSetSchemaTableInfo = getAnnotationSetSchemaTableInfo ();
124- filter = new SimpleFilter ();
125- filter .addInClause (FieldKey .fromParts ("RowId" ), Arrays .asList (ids ));
126- Table .delete (annotationSetSchemaTableInfo , filter );
127+ Table .delete (getAnnotationSetSchemaTableInfo (), new SimpleFilter (FieldKey .fromParts ("RowId" ), ids , CompareType .IN ));
127128
128129 tx .commit ();
129130 return rowsDeleted ;
130131 }
131132 }
132133
133- private Integer insertFeatureAnnotationSet (User user , Container container , String name , String vendor , String description , String comment , BatchValidationException errors )
134+ public Integer insertFeatureAnnotationSet (User user , Container container , String name , String vendor , String description , String comment , BatchValidationException errors )
134135 throws SQLException , BatchValidationException , QueryUpdateServiceException , DuplicateKeyException
135136 {
136137 MicroarrayUserSchema schema = new MicroarrayUserSchema (user , container );
@@ -175,7 +176,7 @@ private Integer insertFeatureAnnotations(User user, Container container, Integer
175176 return -1 ;
176177 }
177178
178- /** Creates feature annotation set AND inserts all feature annotations from TSV */
179+ /** Creates a feature annotation set AND inserts all feature annotations from TSV */
179180 public Integer createFeatureAnnotationSet (User user , Container c , FeatureAnnotationSetController .FeatureAnnotationSetForm form , DataLoader loader , BatchValidationException errors )
180181 throws SQLException , BatchValidationException , QueryUpdateServiceException , DuplicateKeyException
181182 {
@@ -187,48 +188,80 @@ public Integer createFeatureAnnotationSet(User user, Container c, FeatureAnnotat
187188 return -1 ;
188189 }
189190
190- /**
191- * Get feature annotation set by name if it is in scope (current, project, and shared container).
192- */
193- @ Nullable
194- public Integer getFeatureAnnotationSet (Container c , User user , String featureSetName )
191+ private void applyContainerFilter (Container c , User user , SimpleFilter filter )
195192 {
196- SimpleFilter filter = new SimpleFilter ();
197- filter .addCondition (FieldKey .fromParts ("Name" ), featureSetName );
198-
199193 // The container filter matches the assay's featureSet run property lookup
200194 ContainerFilter cf = new ContainerFilter .CurrentPlusProjectAndShared (c , user );
201195 filter .addClause (cf .createFilterClause (MicroarrayUserSchema .getSchema (), FieldKey .fromParts ("container" )));
196+ }
197+
198+ /**
199+ * Get a feature annotation set by name if it is in scope (current, project, and shared container).
200+ */
201+ public @ Nullable Integer getFeatureAnnotationSet (Container c , User user , String featureSetName )
202+ {
203+ return getFeatureAnnotationSet (c , user , new SimpleFilter (FieldKey .fromParts ("Name" ), featureSetName ));
204+ }
205+
206+ /**
207+ * Get a feature annotation set by id if it is in scope (current, project, and shared container).
208+ */
209+ public @ Nullable Integer getFeatureAnnotationSet (Container c , User user , int id )
210+ {
211+ return getFeatureAnnotationSet (c , user , new SimpleFilter (FieldKey .fromParts ("RowId" ), id ));
212+ }
213+
214+ private @ Nullable Integer getFeatureAnnotationSet (Container c , User user , SimpleFilter filter )
215+ {
216+ applyContainerFilter (c , user , filter );
217+ List <Integer > rowIds = new TableSelector (getAnnotationSetSchemaTableInfo (), PageFlowUtil .set ("RowId" ), filter , null ).getArrayList (Integer .class );
202218
203- TableSelector featureAnnotationSelector = new TableSelector (getAnnotationSetSchemaTableInfo (), PageFlowUtil .set ("RowId" ), filter , null );
204- List <Integer > rowIds = featureAnnotationSelector .getArrayList (Integer .class );
205219 // TODO: Order results by container depth
206- if (! rowIds .isEmpty ())
207- return rowIds . get ( 0 ) ;
220+ if (rowIds .isEmpty ())
221+ return null ;
208222
209- return null ;
223+ return rowIds . get ( 0 ) ;
210224 }
211225
212226 /**
213- * Get feature annotation set by id if it is in scope (current, project, and shared container).
227+ * Gets feature annotation sets by id that are in folder scope (current, project, and shared container). The user
228+ * must have the provided permissions in all containers that the feature annotation sets are declared in.
214229 */
215- @ Nullable
216- public Integer getFeatureAnnotationSet (Container c , User user , int id )
230+ public @ NotNull List <Integer > getFeatureAnnotationSets (Container c , User user , Collection <Integer > rowIds , Class <? extends Permission > permission )
217231 {
218- SimpleFilter filter = new SimpleFilter ();
219- filter . addCondition ( FieldKey . fromParts ( "RowId" ), id );
232+ if ( rowIds == null || rowIds . isEmpty ())
233+ return Collections . emptyList ( );
220234
221- // The container filter matches the assay's featureSet run property lookup
222- ContainerFilter cf = new ContainerFilter .CurrentPlusProjectAndShared (c , user );
223- filter .addClause (cf .createFilterClause (MicroarrayUserSchema .getSchema (), FieldKey .fromParts ("container" )));
235+ SimpleFilter filter = new SimpleFilter (FieldKey .fromParts ("RowId" ), rowIds , CompareType .IN );
236+ applyContainerFilter (c , user , filter );
224237
225- TableSelector featureAnnotationSelector = new TableSelector (getAnnotationSetSchemaTableInfo (), PageFlowUtil .set ("RowId" ), filter , null );
226- List <Integer > rowIds = featureAnnotationSelector .getArrayList (Integer .class );
227- // TODO: Order results by container depth
228- if (!rowIds .isEmpty ())
229- return rowIds .get (0 );
238+ List <Integer > setRowIds = new ArrayList <>();
239+ Set <String > processed = new HashSet <>();
240+ try (Results results = new TableSelector (getAnnotationSetSchemaTableInfo (), PageFlowUtil .set ("RowId" , "Container" ), filter , null ).getResults ())
241+ {
242+ while (results .next ())
243+ {
244+ Integer rowId = results .getInt (FieldKey .fromParts ("RowId" ));
245+ String containerId = results .getString (FieldKey .fromParts ("Container" ));
230246
231- return null ;
247+ if (!processed .contains (containerId ))
248+ {
249+ Container container = ContainerManager .getForId (containerId );
250+ if (!container .hasPermission (user , permission ))
251+ throw new UnauthorizedException ("You do not have sufficient permission in " + container .getPath () + " for feature annotation set (" + rowId + ")." );
252+
253+ processed .add (containerId );
254+ }
255+
256+ setRowIds .add (rowId );
257+ }
258+ }
259+ catch (SQLException e )
260+ {
261+ throw new RuntimeSQLException (e );
262+ }
263+
264+ return Collections .unmodifiableList (setRowIds );
232265 }
233266
234267 /**
0 commit comments