extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/servlet/AdminServlet.java

Code
Comments
Other
Rev Date Author Line
3837 12 Apr 16 nicklas 1 package net.sf.basedb.reggie.servlet;
3837 12 Apr 16 nicklas 2
3843 13 Apr 16 nicklas 3 import java.io.Closeable;
3837 12 Apr 16 nicklas 4 import java.io.IOException;
3843 13 Apr 16 nicklas 5 import java.util.ArrayList;
4687 26 Feb 18 nicklas 6 import java.util.Arrays;
3844 14 Apr 16 nicklas 7 import java.util.Collection;
3843 13 Apr 16 nicklas 8 import java.util.HashMap;
3837 12 Apr 16 nicklas 9 import java.util.HashSet;
3912 02 May 16 nicklas 10 import java.util.Iterator;
3843 13 Apr 16 nicklas 11 import java.util.List;
3843 13 Apr 16 nicklas 12 import java.util.Map;
3837 12 Apr 16 nicklas 13 import java.util.Set;
3837 12 Apr 16 nicklas 14 import java.util.TreeSet;
3837 12 Apr 16 nicklas 15
3837 12 Apr 16 nicklas 16 import javax.servlet.ServletException;
3837 12 Apr 16 nicklas 17 import javax.servlet.http.HttpServlet;
3837 12 Apr 16 nicklas 18 import javax.servlet.http.HttpServletRequest;
3837 12 Apr 16 nicklas 19 import javax.servlet.http.HttpServletResponse;
3837 12 Apr 16 nicklas 20
3837 12 Apr 16 nicklas 21 import org.json.simple.JSONArray;
3837 12 Apr 16 nicklas 22 import org.json.simple.JSONObject;
3837 12 Apr 16 nicklas 23
3837 12 Apr 16 nicklas 24 import net.sf.basedb.core.Annotatable;
4687 26 Feb 18 nicklas 25 import net.sf.basedb.core.BasicItem;
3837 12 Apr 16 nicklas 26 import net.sf.basedb.core.DbControl;
3837 12 Apr 16 nicklas 27 import net.sf.basedb.core.DerivedBioAssay;
4687 26 Feb 18 nicklas 28 import net.sf.basedb.core.Directory;
7372 06 Oct 23 nicklas 29 import net.sf.basedb.core.FastAnnotationLoader;
7372 06 Oct 23 nicklas 30 import net.sf.basedb.core.FastAnnotationLoader.FastAnnotation;
4687 26 Feb 18 nicklas 31 import net.sf.basedb.core.File;
3837 12 Apr 16 nicklas 32 import net.sf.basedb.core.FileServer;
4687 26 Feb 18 nicklas 33 import net.sf.basedb.core.Include;
3843 13 Apr 16 nicklas 34 import net.sf.basedb.core.InvalidDataException;
5581 21 Aug 19 nicklas 35 import net.sf.basedb.core.Item;
4687 26 Feb 18 nicklas 36 import net.sf.basedb.core.ItemNotFoundException;
3837 12 Apr 16 nicklas 37 import net.sf.basedb.core.ItemQuery;
3912 02 May 16 nicklas 38 import net.sf.basedb.core.ProgressReporter;
3837 12 Apr 16 nicklas 39 import net.sf.basedb.core.RawBioAssay;
3837 12 Apr 16 nicklas 40 import net.sf.basedb.core.SessionControl;
3912 02 May 16 nicklas 41 import net.sf.basedb.core.SimpleProgressReporter;
4687 26 Feb 18 nicklas 42 import net.sf.basedb.core.Trashcan;
3837 12 Apr 16 nicklas 43 import net.sf.basedb.core.query.Annotations;
5581 21 Aug 19 nicklas 44 import net.sf.basedb.core.query.Hql;
4687 26 Feb 18 nicklas 45 import net.sf.basedb.core.query.Restrictions;
4306 17 Jan 17 nicklas 46 import net.sf.basedb.opengrid.CmdResult;
4306 17 Jan 17 nicklas 47 import net.sf.basedb.opengrid.OpenGrid;
4306 17 Jan 17 nicklas 48 import net.sf.basedb.opengrid.RemoteHost;
4306 17 Jan 17 nicklas 49 import net.sf.basedb.opengrid.RemoteSession;
4306 17 Jan 17 nicklas 50 import net.sf.basedb.opengrid.config.ConnectionInfo;
3837 12 Apr 16 nicklas 51 import net.sf.basedb.reggie.JsonUtil;
3837 12 Apr 16 nicklas 52 import net.sf.basedb.reggie.Reggie;
3844 14 Apr 16 nicklas 53 import net.sf.basedb.reggie.counter.CounterService;
3837 12 Apr 16 nicklas 54 import net.sf.basedb.reggie.dao.Annotationtype;
3837 12 Apr 16 nicklas 55 import net.sf.basedb.reggie.dao.Fileserver;
4687 26 Feb 18 nicklas 56 import net.sf.basedb.reggie.dao.Rawdatatype;
3837 12 Apr 16 nicklas 57 import net.sf.basedb.reggie.dao.ReggieRole;
4687 26 Feb 18 nicklas 58 import net.sf.basedb.reggie.dao.Subtype;
4306 17 Jan 17 nicklas 59 import net.sf.basedb.reggie.grid.ScriptUtil;
3912 02 May 16 nicklas 60 import net.sf.basedb.util.ChainedProgressReporter;
3837 12 Apr 16 nicklas 61 import net.sf.basedb.util.error.ThrowableUtil;
5581 21 Aug 19 nicklas 62 import net.sf.basedb.util.listable.AbstractSourceItemTransformer;
4687 26 Feb 18 nicklas 63 import net.sf.basedb.util.listable.DerivedBioAssayToChildDerivedBioAssayTransformer;
4687 26 Feb 18 nicklas 64 import net.sf.basedb.util.listable.DerivedBioAssayToRawBioAssayTransformer;
4687 26 Feb 18 nicklas 65 import net.sf.basedb.util.listable.TransformContext;
3837 12 Apr 16 nicklas 66
3837 12 Apr 16 nicklas 67 /**
3837 12 Apr 16 nicklas 68   Other administrative tasks.
3837 12 Apr 16 nicklas 69   
3837 12 Apr 16 nicklas 70   @author nicklas
3837 12 Apr 16 nicklas 71    @since 4.3
3837 12 Apr 16 nicklas 72 */
3837 12 Apr 16 nicklas 73 public class AdminServlet 
3837 12 Apr 16 nicklas 74   extends HttpServlet 
3837 12 Apr 16 nicklas 75 {
3837 12 Apr 16 nicklas 76   private static final long serialVersionUID = -5241256019969726399L;
3837 12 Apr 16 nicklas 77
3837 12 Apr 16 nicklas 78
3837 12 Apr 16 nicklas 79   public AdminServlet()
3837 12 Apr 16 nicklas 80   {}
3837 12 Apr 16 nicklas 81
3837 12 Apr 16 nicklas 82   @Override
3837 12 Apr 16 nicklas 83   protected void doGet(HttpServletRequest req, HttpServletResponse resp)
3837 12 Apr 16 nicklas 84     throws ServletException, IOException 
3837 12 Apr 16 nicklas 85   {
3837 12 Apr 16 nicklas 86     String cmd = req.getParameter("cmd");
3837 12 Apr 16 nicklas 87     JsonUtil.setJsonResponseHeaders(resp);
3837 12 Apr 16 nicklas 88     
3837 12 Apr 16 nicklas 89     JSONObject json = new JSONObject();
3837 12 Apr 16 nicklas 90     json.put("status", "ok");
3837 12 Apr 16 nicklas 91   
3975 26 May 16 nicklas 92     SessionControl sc = Reggie.getSessionControl(req);
3837 12 Apr 16 nicklas 93     DbControl dc = null;
3837 12 Apr 16 nicklas 94     
3837 12 Apr 16 nicklas 95     try
3837 12 Apr 16 nicklas 96     {
3843 13 Apr 16 nicklas 97       if ("FindStrayFolders".equals(cmd))
3837 12 Apr 16 nicklas 98       {
6336 16 Jun 21 nicklas 99         dc = sc.newDbControl(":Stray files wizard");
3837 12 Apr 16 nicklas 100         
3837 12 Apr 16 nicklas 101         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.ADMINISTRATOR);
3837 12 Apr 16 nicklas 102         
7372 06 Oct 23 nicklas 103         FastAnnotationLoader<String> dffLoader = Annotationtype.DATA_FILES_FOLDER.get(dc).getFastLoader(dc);
3912 02 May 16 nicklas 104         SimpleProgressReporter progress = new SimpleProgressReporter(null);
3912 02 May 16 nicklas 105         ChainedProgressReporter chained = new ChainedProgressReporter(progress);
3837 12 Apr 16 nicklas 106         
3912 02 May 16 nicklas 107         sc.setSessionSetting("stray-files-progress", progress);
3912 02 May 16 nicklas 108         
3837 12 Apr 16 nicklas 109         // Load known folders from the "DataFilesFolder" annotation
3837 12 Apr 16 nicklas 110         Set<String> knownFolders = new HashSet<String>();
6101 15 Jan 21 nicklas 111         // Some static folders that are not linked to any items
3837 12 Apr 16 nicklas 112         knownFolders.add("/debug");
6101 15 Jan 21 nicklas 113         knownFolders.add("/he-hiresscans");
6101 15 Jan 21 nicklas 114         // Derived bioassays
3912 02 May 16 nicklas 115         progress.display(1, "Loading known folders...");
3912 02 May 16 nicklas 116         chained.setRange(5, 19);
7372 06 Oct 23 nicklas 117         loadDataFileFolders(dc, dffLoader, DerivedBioAssay.getQuery(), knownFolders, chained);
6101 15 Jan 21 nicklas 118         // Raw bioassays
3912 02 May 16 nicklas 119         progress.display(20, "Loading known folders...");
3912 02 May 16 nicklas 120         chained.setRange(21, 29);
7372 06 Oct 23 nicklas 121         loadDataFileFolders(dc, dffLoader, RawBioAssay.getQuery(), knownFolders, chained);
3837 12 Apr 16 nicklas 122         
3837 12 Apr 16 nicklas 123         // List all folders in the file server archives
3837 12 Apr 16 nicklas 124         Set<RemoteFolder> remoteFolders = new TreeSet<RemoteFolder>();
3912 02 May 16 nicklas 125         progress.display(30, "Checking ProjectArchive...");
3837 12 Apr 16 nicklas 126         loadRemoteFolders(dc, Fileserver.PROJECT_ARCHIVE, remoteFolders);
7047 14 Feb 23 nicklas 127         progress.display(50, "Checking ProjectArchiveDNA...");
7047 14 Feb 23 nicklas 128         loadRemoteFolders(dc, Fileserver.PROJECT_ARCHIVE_DNA, remoteFolders);
7047 14 Feb 23 nicklas 129         progress.display(70, "Checking ExternalArchive...");
3837 12 Apr 16 nicklas 130         loadRemoteFolders(dc, Fileserver.EXTERNAL_ARCHIVE, remoteFolders);
3837 12 Apr 16 nicklas 131         
3912 02 May 16 nicklas 132         progress.display(90, "Comparing known folders with actual folders...");
3844 14 Apr 16 nicklas 133         List<RemoteFolder> strayFolders = findStrayFolders(remoteFolders, knownFolders);
3844 14 Apr 16 nicklas 134
3837 12 Apr 16 nicklas 135         JSONArray jsonStray = new JSONArray();
3844 14 Apr 16 nicklas 136         for (RemoteFolder rf : strayFolders)
3837 12 Apr 16 nicklas 137         {
3844 14 Apr 16 nicklas 138           jsonStray.add(rf.asJSONObject());
3837 12 Apr 16 nicklas 139         }
3912 02 May 16 nicklas 140         progress.display(100, "Done");
3837 12 Apr 16 nicklas 141         
3843 13 Apr 16 nicklas 142         // Keep the folders in the session scope so we can reference them by index
3843 13 Apr 16 nicklas 143         // when removing. This is a securit measure so we don't have to accept
3843 13 Apr 16 nicklas 144         // just any path coming from the browser
3843 13 Apr 16 nicklas 145         sc.setSessionSetting("net.sf.basedb.reggie.stray-folders", strayFolders);
3843 13 Apr 16 nicklas 146         
3844 14 Apr 16 nicklas 147         // Update counter
3844 14 Apr 16 nicklas 148         CounterService.getInstance().setStrayFoldersCount(strayFolders.size());
3844 14 Apr 16 nicklas 149         
3837 12 Apr 16 nicklas 150         json.put("strayFolders", jsonStray);
3838 13 Apr 16 nicklas 151         json.put("totalFolders", remoteFolders.size());
3837 12 Apr 16 nicklas 152         
3837 12 Apr 16 nicklas 153         JSONArray jsonFileServers = new JSONArray();
3837 12 Apr 16 nicklas 154         jsonFileServers.add(Fileserver.PROJECT_ARCHIVE.asJSONObject(dc));
7047 14 Feb 23 nicklas 155         jsonFileServers.add(Fileserver.PROJECT_ARCHIVE_DNA.asJSONObject(dc));
3837 12 Apr 16 nicklas 156         jsonFileServers.add(Fileserver.EXTERNAL_ARCHIVE.asJSONObject(dc));
3837 12 Apr 16 nicklas 157         json.put("fileServers", jsonFileServers);
3837 12 Apr 16 nicklas 158       }
4687 26 Feb 18 nicklas 159       else if ("GetSecondayAnalysisCleanupCount".equals(cmd))
4687 26 Feb 18 nicklas 160       {
6336 16 Jun 21 nicklas 161         dc = sc.newDbControl(":Secondary analysis cleanup");
4687 26 Feb 18 nicklas 162         ItemQuery<DerivedBioAssay> query = DerivedBioAssay.getQuery();
5581 21 Aug 19 nicklas 163         
4687 26 Feb 18 nicklas 164         query.setIncludes(Arrays.asList(Include.IN_PROJECT, Include.REMOVED));
4687 26 Feb 18 nicklas 165         query.restrict(Restrictions.or(
4687 26 Feb 18 nicklas 166             Subtype.DEMUXED_SEQUENCES.restriction(dc, null),
4687 26 Feb 18 nicklas 167             Subtype.MERGED_SEQUENCES.restriction(dc, null),
4687 26 Feb 18 nicklas 168             Subtype.MASKED_SEQUENCES.restriction(dc, null),
7345 11 Sep 23 nicklas 169             Subtype.ALIGNED_SEQUENCES.restriction(dc, null),
7345 11 Sep 23 nicklas 170             Subtype.COPY_NUMBER.restriction(dc, null),
7345 11 Sep 23 nicklas 171             Subtype.METHYLATION.restriction(dc, null),
7345 11 Sep 23 nicklas 172             Subtype.GENOTYPE_CALL.restriction(dc, null)
4687 26 Feb 18 nicklas 173           ));
4687 26 Feb 18 nicklas 174         
4687 26 Feb 18 nicklas 175         Set<Integer> dbaSelected = new HashSet<>(query.idList(dc));
4687 26 Feb 18 nicklas 176         
4687 26 Feb 18 nicklas 177         TransformContext ctx = new TransformContext(dc);
4687 26 Feb 18 nicklas 178         DerivedBioAssayToChildDerivedBioAssayTransformer childT = new DerivedBioAssayToChildDerivedBioAssayTransformer(true);
4687 26 Feb 18 nicklas 179         Set<Integer> dbaAll = childT.transform(ctx, dbaSelected);
4687 26 Feb 18 nicklas 180         DerivedBioAssayToRawBioAssayTransformer rawT = new DerivedBioAssayToRawBioAssayTransformer();
4687 26 Feb 18 nicklas 181         Set<Integer> rawChildren = rawT.transform(ctx, dbaAll);
4687 26 Feb 18 nicklas 182         
4687 26 Feb 18 nicklas 183         ItemQuery<RawBioAssay> rawQuery = RawBioAssay.getQuery();
4687 26 Feb 18 nicklas 184         rawQuery.setIncludes(Arrays.asList(Include.IN_PROJECT, Include.REMOVED));
4687 26 Feb 18 nicklas 185         rawQuery.restrict(Restrictions.or(
4687 26 Feb 18 nicklas 186             Rawdatatype.CUFFLINKS.restriction(dc, null),
5722 13 Nov 19 nicklas 187             Rawdatatype.STRINGTIE.restriction(dc, null),
5722 13 Nov 19 nicklas 188             Rawdatatype.VARIANT_CALL.restriction(dc, null)
4687 26 Feb 18 nicklas 189           ));
4687 26 Feb 18 nicklas 190         
5581 21 Aug 19 nicklas 191         Set<Integer> rawSelected = new HashSet<>(rawQuery.idList(dc));
5581 21 Aug 19 nicklas 192         Set<Integer> rawAll = new HashSet<>(rawSelected);
5581 21 Aug 19 nicklas 193         rawAll.addAll(rawChildren);
5581 21 Aug 19 nicklas 194         
4687 26 Feb 18 nicklas 195         json.put("countDerivedBioAssays", dbaSelected.size());
5581 21 Aug 19 nicklas 196         json.put("countDerivedBioAssayChildren", dbaAll.size() - dbaSelected.size());
5581 21 Aug 19 nicklas 197         json.put("countRawBioAssays", rawAll.size());
4687 26 Feb 18 nicklas 198         
5581 21 Aug 19 nicklas 199         ToFileTransformer dbaFilesT = new ToFileTransformer(Item.DERIVEDBIOASSAY);
5581 21 Aug 19 nicklas 200         Set<Integer> dbaFiles = dbaFilesT.transform(ctx, dbaAll);
5581 21 Aug 19 nicklas 201
5581 21 Aug 19 nicklas 202         ToFileTransformer rbaFilesT = new ToFileTransformer(Item.RAWBIOASSAY);
5581 21 Aug 19 nicklas 203         Set<Integer> rbaFiles = rbaFilesT.transform(ctx, rawAll);
5581 21 Aug 19 nicklas 204
5581 21 Aug 19 nicklas 205         Set<Integer> allFiles = new HashSet<>(dbaFiles);
5581 21 Aug 19 nicklas 206         allFiles.addAll(rbaFiles);
5581 21 Aug 19 nicklas 207         
5581 21 Aug 19 nicklas 208         json.put("countFiles", allFiles.size());
5581 21 Aug 19 nicklas 209         
4687 26 Feb 18 nicklas 210         dc.commit();
4687 26 Feb 18 nicklas 211       }
6684 20 Apr 22 nicklas 212       else if ("ReloadConfig".equals(cmd))
6684 20 Apr 22 nicklas 213       {
6684 20 Apr 22 nicklas 214         dc = sc.newDbControl(":Reload config");
6684 20 Apr 22 nicklas 215         ReggieRole.checkPermission(dc, "'" + cmd + "'", ReggieRole.ADMINISTRATOR);
6684 20 Apr 22 nicklas 216         Reggie.reloadConfig();
6684 20 Apr 22 nicklas 217         dc.close();
6684 20 Apr 22 nicklas 218       }
3837 12 Apr 16 nicklas 219     }
3837 12 Apr 16 nicklas 220     catch (Throwable t)
3837 12 Apr 16 nicklas 221     {
3837 12 Apr 16 nicklas 222       t.printStackTrace();
3837 12 Apr 16 nicklas 223       json.clear();
3837 12 Apr 16 nicklas 224       json.put("status", "error");
3837 12 Apr 16 nicklas 225       json.put("message", t.getMessage());
3837 12 Apr 16 nicklas 226       json.put("stacktrace", ThrowableUtil.stackTraceToString(t));
3837 12 Apr 16 nicklas 227     }
3837 12 Apr 16 nicklas 228     finally
3837 12 Apr 16 nicklas 229     {
3837 12 Apr 16 nicklas 230       if (dc != null) dc.close();
3912 02 May 16 nicklas 231       if (sc != null) sc.setSessionSetting("stray-files-progress", null);
3837 12 Apr 16 nicklas 232       json.writeJSONString(resp.getWriter());
3837 12 Apr 16 nicklas 233     }
3837 12 Apr 16 nicklas 234     
3837 12 Apr 16 nicklas 235   }
3843 13 Apr 16 nicklas 236   
3843 13 Apr 16 nicklas 237   @SuppressWarnings("unchecked")
3843 13 Apr 16 nicklas 238   @Override
3843 13 Apr 16 nicklas 239   protected void doPost(HttpServletRequest req, HttpServletResponse resp)
3843 13 Apr 16 nicklas 240     throws ServletException, IOException 
3843 13 Apr 16 nicklas 241   {
3843 13 Apr 16 nicklas 242     String cmd = req.getParameter("cmd");
3843 13 Apr 16 nicklas 243     JsonUtil.setJsonResponseHeaders(resp);
3843 13 Apr 16 nicklas 244     
3843 13 Apr 16 nicklas 245     JSONObject json = new JSONObject();
3843 13 Apr 16 nicklas 246     json.put("status", "ok");
3843 13 Apr 16 nicklas 247     JSONArray jsonMessages = new JSONArray();
3843 13 Apr 16 nicklas 248   
3975 26 May 16 nicklas 249     final SessionControl sc = Reggie.getSessionControl(req);
3843 13 Apr 16 nicklas 250     DbControl dc = null;
3843 13 Apr 16 nicklas 251     try
3843 13 Apr 16 nicklas 252     {
3843 13 Apr 16 nicklas 253       if ("DeleteStrayFolders".equals(cmd))
3843 13 Apr 16 nicklas 254       {
6336 16 Jun 21 nicklas 255         dc = sc.newDbControl(":Stray files wizard");
3843 13 Apr 16 nicklas 256         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.ADMINISTRATOR);
3843 13 Apr 16 nicklas 257         
3843 13 Apr 16 nicklas 258         List<RemoteFolder> strayFolders = (List<RemoteFolder>)sc.getSessionSetting("net.sf.basedb.reggie.stray-folders");
3843 13 Apr 16 nicklas 259         if (strayFolders == null)
3843 13 Apr 16 nicklas 260         {
3843 13 Apr 16 nicklas 261           throw new InvalidDataException("Could not find any stray folders");
3843 13 Apr 16 nicklas 262         }
3843 13 Apr 16 nicklas 263         sc.setSessionSetting("net.sf.basedb.reggie.stray-folders", null);
3843 13 Apr 16 nicklas 264         
3843 13 Apr 16 nicklas 265         Map<Integer, ConnectedHost> hosts = new HashMap<Integer, ConnectedHost>();
3837 12 Apr 16 nicklas 266
3843 13 Apr 16 nicklas 267         JSONObject jsonReq = JsonUtil.parseRequest(req);
3843 13 Apr 16 nicklas 268         JSONArray jsonFolders = (JSONArray)jsonReq.get("folders");
3844 14 Apr 16 nicklas 269         int numDeleted = 0;
3843 13 Apr 16 nicklas 270         try
3843 13 Apr 16 nicklas 271         {
3843 13 Apr 16 nicklas 272           for (int i = 0; i < jsonFolders.size(); i++)
3843 13 Apr 16 nicklas 273           {
3843 13 Apr 16 nicklas 274             int index = ((Number)jsonFolders.get(i)).intValue();
3843 13 Apr 16 nicklas 275             if (index < 0 || index >= strayFolders.size())
3843 13 Apr 16 nicklas 276             {
3843 13 Apr 16 nicklas 277               jsonMessages.add("[Error] Invalid folder index at position " + i + ": " + index);
3843 13 Apr 16 nicklas 278             }
3843 13 Apr 16 nicklas 279             else
3843 13 Apr 16 nicklas 280             {
3843 13 Apr 16 nicklas 281             
3843 13 Apr 16 nicklas 282               RemoteFolder strayFolder = strayFolders.get(index);
3843 13 Apr 16 nicklas 283               ConnectedHost host = hosts.get(strayFolder.getFileServer());
3843 13 Apr 16 nicklas 284               if (host == null)
3843 13 Apr 16 nicklas 285               {
3843 13 Apr 16 nicklas 286                 try
3843 13 Apr 16 nicklas 287                 {
3843 13 Apr 16 nicklas 288                   FileServer server = FileServer.getById(dc, strayFolder.getFileServer());
3843 13 Apr 16 nicklas 289                   host = new ConnectedHost(server);
3843 13 Apr 16 nicklas 290                   hosts.put(strayFolder.getFileServer(), host);
3843 13 Apr 16 nicklas 291                 }
3843 13 Apr 16 nicklas 292                 catch (Exception ex)
3843 13 Apr 16 nicklas 293                 {
3843 13 Apr 16 nicklas 294                   jsonMessages.add("[Error] " + strayFolder.getPath() + ": " +ex.getMessage());
3843 13 Apr 16 nicklas 295                 }
3843 13 Apr 16 nicklas 296               }
3843 13 Apr 16 nicklas 297               if (host != null)
3843 13 Apr 16 nicklas 298               {
3843 13 Apr 16 nicklas 299                 String rmCmd = "rm -rfv " + host.server.getRootPath() + strayFolder.getPath();
4306 17 Jan 17 nicklas 300                 CmdResult<String> rm = host.executeCmd(rmCmd);
3843 13 Apr 16 nicklas 301                 if (rm.getExitStatus() == 0)
3843 13 Apr 16 nicklas 302                 {
3844 14 Apr 16 nicklas 303                   numDeleted++;
3843 13 Apr 16 nicklas 304                   String[] lines = rm.getStdout().split("\\n");
3843 13 Apr 16 nicklas 305                   jsonMessages.add(strayFolder.getPath() + ": " + lines.length + " files/directories deleted");
3843 13 Apr 16 nicklas 306                 }
3843 13 Apr 16 nicklas 307                 else
3843 13 Apr 16 nicklas 308                 {
3843 13 Apr 16 nicklas 309                   jsonMessages.add("[Error] " + strayFolder.getPath() + ": [" + rm.getExitStatus()+"] " + rm.getStderr());
3843 13 Apr 16 nicklas 310                 }
3843 13 Apr 16 nicklas 311               }
3843 13 Apr 16 nicklas 312             }
3843 13 Apr 16 nicklas 313           }
3843 13 Apr 16 nicklas 314         }
3843 13 Apr 16 nicklas 315         finally
3843 13 Apr 16 nicklas 316         {
3843 13 Apr 16 nicklas 317           for (ConnectedHost host : hosts.values())
3843 13 Apr 16 nicklas 318           {
4306 17 Jan 17 nicklas 319             OpenGrid.close(host);
3843 13 Apr 16 nicklas 320           }
3843 13 Apr 16 nicklas 321         }
3844 14 Apr 16 nicklas 322
3844 14 Apr 16 nicklas 323         // Update counter
3844 14 Apr 16 nicklas 324         CounterService.getInstance().setStrayFoldersCount(strayFolders.size()-numDeleted);
3843 13 Apr 16 nicklas 325         dc.close();
3843 13 Apr 16 nicklas 326       }
4687 26 Feb 18 nicklas 327       else if ("SecondaryAnalysisCleanup".equals(cmd))
4687 26 Feb 18 nicklas 328       {
6336 16 Jun 21 nicklas 329         dc = sc.newDbControl(":Secondary analysis cleanup");
4687 26 Feb 18 nicklas 330         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.ADMINISTRATOR);
4687 26 Feb 18 nicklas 331
4687 26 Feb 18 nicklas 332         SimpleProgressReporter progress = new SimpleProgressReporter(null);
4687 26 Feb 18 nicklas 333         sc.setSessionSetting("secondary-cleanup-progress", progress);
4687 26 Feb 18 nicklas 334         progress.display(1, "Loading items...");
4687 26 Feb 18 nicklas 335
4687 26 Feb 18 nicklas 336         ItemQuery<DerivedBioAssay> dbaQuery = DerivedBioAssay.getQuery();
4687 26 Feb 18 nicklas 337         dbaQuery.setIncludes(Arrays.asList(Include.IN_PROJECT, Include.REMOVED));
4687 26 Feb 18 nicklas 338         dbaQuery.restrict(Restrictions.or(
4687 26 Feb 18 nicklas 339             Subtype.DEMUXED_SEQUENCES.restriction(dc, null),
4687 26 Feb 18 nicklas 340             Subtype.MERGED_SEQUENCES.restriction(dc, null),
4687 26 Feb 18 nicklas 341             Subtype.MASKED_SEQUENCES.restriction(dc, null),
7345 11 Sep 23 nicklas 342             Subtype.ALIGNED_SEQUENCES.restriction(dc, null),
7345 11 Sep 23 nicklas 343             Subtype.COPY_NUMBER.restriction(dc, null),
7345 11 Sep 23 nicklas 344             Subtype.METHYLATION.restriction(dc, null),
7345 11 Sep 23 nicklas 345             Subtype.GENOTYPE_CALL.restriction(dc, null)
4687 26 Feb 18 nicklas 346             ));
4687 26 Feb 18 nicklas 347         
4687 26 Feb 18 nicklas 348         ItemQuery<RawBioAssay> rbaQuery = RawBioAssay.getQuery();
4687 26 Feb 18 nicklas 349         rbaQuery.setIncludes(Arrays.asList(Include.IN_PROJECT, Include.REMOVED));
4687 26 Feb 18 nicklas 350         rbaQuery.restrict(Restrictions.or(
4687 26 Feb 18 nicklas 351             Rawdatatype.CUFFLINKS.restriction(dc, null),
5722 13 Nov 19 nicklas 352             Rawdatatype.STRINGTIE.restriction(dc, null),
5722 13 Nov 19 nicklas 353             Rawdatatype.VARIANT_CALL.restriction(dc, null)
4687 26 Feb 18 nicklas 354           ));
4687 26 Feb 18 nicklas 355
4687 26 Feb 18 nicklas 356         List<Integer> dbaList = dbaQuery.idList(dc);
4687 26 Feb 18 nicklas 357         List<Integer> rbaList = rbaQuery.idList(dc);
4687 26 Feb 18 nicklas 358         int numDba = dbaList.size();
4687 26 Feb 18 nicklas 359         int numRba = rbaList.size();
4687 26 Feb 18 nicklas 360         int totalItems = numDba + numRba;
4687 26 Feb 18 nicklas 361         
4687 26 Feb 18 nicklas 362         List<BasicItem> toDelete = new ArrayList<BasicItem>();
4687 26 Feb 18 nicklas 363         int count = 0;
4687 26 Feb 18 nicklas 364         int numTotalDeleted = 0;
4687 26 Feb 18 nicklas 365         int numPrimaryDeleted = 0;
4687 26 Feb 18 nicklas 366         int numChildsDeleted = 0;
4687 26 Feb 18 nicklas 367         int itemsInBatch = 0;
4687 26 Feb 18 nicklas 368         
4687 26 Feb 18 nicklas 369         for (Integer id : rbaList)
4687 26 Feb 18 nicklas 370         {
4687 26 Feb 18 nicklas 371           count++;
4687 26 Feb 18 nicklas 372           
4687 26 Feb 18 nicklas 373           RawBioAssay rba = RawBioAssay.getById(dc, id);
4687 26 Feb 18 nicklas 374           removeRawBioAssayAndLinkedItems(dc, rba, toDelete);
4687 26 Feb 18 nicklas 375           itemsInBatch++;
4687 26 Feb 18 nicklas 376           
4687 26 Feb 18 nicklas 377           // Batch around 1000 items in one go, then we restart in a new transaction
4687 26 Feb 18 nicklas 378           if (toDelete.size() > 1000 || count == numRba)
4687 26 Feb 18 nicklas 379           {
5415 09 May 19 nicklas 380             progress.display(3 + ((95 * count) / totalItems), count + " of " + totalItems + " done. Flushing to database (this may take some time)...");
4687 26 Feb 18 nicklas 381             dc.commit();
4687 26 Feb 18 nicklas 382             try
4687 26 Feb 18 nicklas 383             {
4687 26 Feb 18 nicklas 384               numTotalDeleted += Trashcan.delete(sc, toDelete, false, null);
4687 26 Feb 18 nicklas 385               numPrimaryDeleted += itemsInBatch;
4687 26 Feb 18 nicklas 386             }
4687 26 Feb 18 nicklas 387             catch (RuntimeException ex)
4687 26 Feb 18 nicklas 388             {
4687 26 Feb 18 nicklas 389               ex.printStackTrace();
4687 26 Feb 18 nicklas 390               jsonMessages.add("[Error]Some items could not be deleted: " + ex.getMessage());
4687 26 Feb 18 nicklas 391             }
4687 26 Feb 18 nicklas 392             finally
4687 26 Feb 18 nicklas 393             {
4687 26 Feb 18 nicklas 394               toDelete.clear();
4687 26 Feb 18 nicklas 395               itemsInBatch = 0;
4687 26 Feb 18 nicklas 396             }
6336 16 Jun 21 nicklas 397             dc = sc.newDbControl(dc.getName());
4687 26 Feb 18 nicklas 398           }
4687 26 Feb 18 nicklas 399         }
4687 26 Feb 18 nicklas 400         
4687 26 Feb 18 nicklas 401         for (Integer id : dbaList)
4687 26 Feb 18 nicklas 402         {
4687 26 Feb 18 nicklas 403           count++;
4687 26 Feb 18 nicklas 404
4687 26 Feb 18 nicklas 405           try
4687 26 Feb 18 nicklas 406           {
4687 26 Feb 18 nicklas 407             DerivedBioAssay dba = DerivedBioAssay.getById(dc, id);
4687 26 Feb 18 nicklas 408             removeDerivedBioAssayAndLinkedItems(dc, dba, toDelete);
4687 26 Feb 18 nicklas 409           }
4687 26 Feb 18 nicklas 410           catch (ItemNotFoundException ex)
4687 26 Feb 18 nicklas 411           {
4687 26 Feb 18 nicklas 412             jsonMessages.add(ex.getMessage());
4687 26 Feb 18 nicklas 413           }
4687 26 Feb 18 nicklas 414           itemsInBatch++;
4687 26 Feb 18 nicklas 415           
4687 26 Feb 18 nicklas 416           // Batch around 1000 items in one go, then we restart in a new transaction
4687 26 Feb 18 nicklas 417           if (toDelete.size() > 1000 || count == totalItems)
4687 26 Feb 18 nicklas 418           {
5415 09 May 19 nicklas 419             progress.display(3 + ((95 * count) / totalItems), count + " of " + totalItems + " done. Flushing to database (this may take some time)...");
4687 26 Feb 18 nicklas 420             dc.commit();
4687 26 Feb 18 nicklas 421             try
4687 26 Feb 18 nicklas 422             {
4687 26 Feb 18 nicklas 423               numTotalDeleted += Trashcan.delete(sc, toDelete, false, null);
4687 26 Feb 18 nicklas 424               numPrimaryDeleted += itemsInBatch;
4687 26 Feb 18 nicklas 425             }
4687 26 Feb 18 nicklas 426             catch (RuntimeException ex)
4687 26 Feb 18 nicklas 427             {
4687 26 Feb 18 nicklas 428               ex.printStackTrace();
4687 26 Feb 18 nicklas 429               jsonMessages.add("[Error]Some items could not be deleted: " + ex.getMessage());
4687 26 Feb 18 nicklas 430             }
4687 26 Feb 18 nicklas 431             finally
4687 26 Feb 18 nicklas 432             {
4687 26 Feb 18 nicklas 433               toDelete.clear();
4687 26 Feb 18 nicklas 434               itemsInBatch = 0;
4687 26 Feb 18 nicklas 435             }
4687 26 Feb 18 nicklas 436             
6336 16 Jun 21 nicklas 437             dc = sc.newDbControl(dc.getName());
4687 26 Feb 18 nicklas 438           }
4687 26 Feb 18 nicklas 439         }
4687 26 Feb 18 nicklas 440         
4687 26 Feb 18 nicklas 441         progress.display(100, count + " of " + totalItems + " done.");
4687 26 Feb 18 nicklas 442         if (numTotalDeleted > 0)
4687 26 Feb 18 nicklas 443         {
4687 26 Feb 18 nicklas 444           jsonMessages.add(numPrimaryDeleted + " items deleted");
4687 26 Feb 18 nicklas 445           if (numTotalDeleted > numPrimaryDeleted)
4687 26 Feb 18 nicklas 446           {
4687 26 Feb 18 nicklas 447             jsonMessages.add((numTotalDeleted - numPrimaryDeleted) + " child items and other linked items (eg. files and directories) deleted");
4687 26 Feb 18 nicklas 448           }
4687 26 Feb 18 nicklas 449           
4687 26 Feb 18 nicklas 450           jsonMessages.add("Do not forget to run the 'Stray files wizard' to delete files from the project archive!");
4687 26 Feb 18 nicklas 451         }
3843 13 Apr 16 nicklas 452       
4687 26 Feb 18 nicklas 453         dc.close();
4687 26 Feb 18 nicklas 454         CounterService.getInstance().setForceCount();
4687 26 Feb 18 nicklas 455       }
4687 26 Feb 18 nicklas 456       
3843 13 Apr 16 nicklas 457       json.put("messages", jsonMessages);
3843 13 Apr 16 nicklas 458     }
3843 13 Apr 16 nicklas 459     catch (Throwable t)
3843 13 Apr 16 nicklas 460     {
3843 13 Apr 16 nicklas 461       t.printStackTrace();
3843 13 Apr 16 nicklas 462       json.clear();
3843 13 Apr 16 nicklas 463       json.put("status", "error");
3843 13 Apr 16 nicklas 464       json.put("message", t.getMessage());
3843 13 Apr 16 nicklas 465       json.put("stacktrace", ThrowableUtil.stackTraceToString(t));
3843 13 Apr 16 nicklas 466     }
3843 13 Apr 16 nicklas 467     finally
3843 13 Apr 16 nicklas 468     {
3843 13 Apr 16 nicklas 469       if (dc != null) dc.close();
3843 13 Apr 16 nicklas 470       json.writeJSONString(resp.getWriter());
3843 13 Apr 16 nicklas 471     }
3843 13 Apr 16 nicklas 472   }
4687 26 Feb 18 nicklas 473   
4687 26 Feb 18 nicklas 474   
4687 26 Feb 18 nicklas 475   private void removeRawBioAssayAndLinkedItems(DbControl dc, RawBioAssay rba, List<BasicItem> toDelete)
4687 26 Feb 18 nicklas 476   {
4687 26 Feb 18 nicklas 477     rba.setRemoved(true);
4687 26 Feb 18 nicklas 478     toDelete.add(rba);
4687 26 Feb 18 nicklas 479     List<File> files = Reggie.removeAttachedFiles(dc, rba);
4687 26 Feb 18 nicklas 480     List<Directory> directories = Reggie.removeDirectories(dc, files);
4687 26 Feb 18 nicklas 481     toDelete.addAll(files);
4687 26 Feb 18 nicklas 482     toDelete.addAll(directories);
4687 26 Feb 18 nicklas 483   }
4687 26 Feb 18 nicklas 484   
4687 26 Feb 18 nicklas 485   private void removeDerivedBioAssayAndLinkedItems(DbControl dc, DerivedBioAssay dba, List<BasicItem> toDelete)
4687 26 Feb 18 nicklas 486   {
4687 26 Feb 18 nicklas 487     ItemQuery<RawBioAssay> rawQuery = dba.getRawBioAssays();
4687 26 Feb 18 nicklas 488     rawQuery.setIncludes(Include.ALL);
4687 26 Feb 18 nicklas 489     for (RawBioAssay rba : rawQuery.list(dc))
4687 26 Feb 18 nicklas 490     {
4687 26 Feb 18 nicklas 491       removeRawBioAssayAndLinkedItems(dc, rba, toDelete);
4687 26 Feb 18 nicklas 492     }
4687 26 Feb 18 nicklas 493     
4687 26 Feb 18 nicklas 494     ItemQuery<DerivedBioAssay> dbaQuery = dba.getChildren();
4687 26 Feb 18 nicklas 495     dbaQuery.setIncludes(Include.ALL);
4687 26 Feb 18 nicklas 496     for (DerivedBioAssay child : dbaQuery.list(dc))
4687 26 Feb 18 nicklas 497     {
4687 26 Feb 18 nicklas 498       removeDerivedBioAssayAndLinkedItems(dc, child, toDelete);
4687 26 Feb 18 nicklas 499     }
4687 26 Feb 18 nicklas 500     
4687 26 Feb 18 nicklas 501     dba.setRemoved(true);
4687 26 Feb 18 nicklas 502     toDelete.add(dba);
4687 26 Feb 18 nicklas 503     List<File> files = Reggie.removeAttachedFiles(dc, dba);
4687 26 Feb 18 nicklas 504     List<Directory> directories = Reggie.removeDirectories(dc, files);
4687 26 Feb 18 nicklas 505     toDelete.addAll(files);
4687 26 Feb 18 nicklas 506     toDelete.addAll(directories);
4687 26 Feb 18 nicklas 507   }
3843 13 Apr 16 nicklas 508
3837 12 Apr 16 nicklas 509   /**
3837 12 Apr 16 nicklas 510     Load the "DataFilesFolder" annotation for all items returned by the query.
3837 12 Apr 16 nicklas 511     The paths are added to the 'knownFolder' set.
3837 12 Apr 16 nicklas 512     @return The number of new paths loaded
3837 12 Apr 16 nicklas 513    */
7372 06 Oct 23 nicklas 514   public static int loadDataFileFolders(DbControl dc, FastAnnotationLoader<String> loader, ItemQuery<? extends Annotatable> query, Set<String> knownFolders, ProgressReporter progress)
3837 12 Apr 16 nicklas 515   {
3837 12 Apr 16 nicklas 516     int sizeBefore = knownFolders.size();
3837 12 Apr 16 nicklas 517     
3837 12 Apr 16 nicklas 518     query.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
3837 12 Apr 16 nicklas 519     query.join(Annotations.innerJoin(Annotationtype.DATA_FILES_FOLDER.load(dc), "dff"));
7372 06 Oct 23 nicklas 520     
7372 06 Oct 23 nicklas 521     Iterator<FastAnnotation<String>> it = loader.load(query);
7372 06 Oct 23 nicklas 522     
3912 02 May 16 nicklas 523     long totalCount = query.count(dc);
3912 02 May 16 nicklas 524     long count = 0;
3912 02 May 16 nicklas 525     while (it.hasNext())
3837 12 Apr 16 nicklas 526     {
3912 02 May 16 nicklas 527       if (count % 100 == 0 && progress != null)
7372 06 Oct 23 nicklas 528       {
3912 02 May 16 nicklas 529         progress.display((int)((100 * count) / totalCount), null);
7372 06 Oct 23 nicklas 530       }
3912 02 May 16 nicklas 531       count++;
3912 02 May 16 nicklas 532       
7372 06 Oct 23 nicklas 533       String path = it.next().value;
3837 12 Apr 16 nicklas 534       knownFolders.add(path);
3837 12 Apr 16 nicklas 535       // Add parent paths
3837 12 Apr 16 nicklas 536       int i;
3837 12 Apr 16 nicklas 537       while ((i = path.lastIndexOf("/")) > 0)
3837 12 Apr 16 nicklas 538       {
3837 12 Apr 16 nicklas 539         path = path.substring(0, i);
3837 12 Apr 16 nicklas 540         if (!knownFolders.add(path)) break;
3837 12 Apr 16 nicklas 541       }
3837 12 Apr 16 nicklas 542     }
3837 12 Apr 16 nicklas 543     
3837 12 Apr 16 nicklas 544     // Return the number of new folders added
3837 12 Apr 16 nicklas 545     return knownFolders.size() - sizeBefore;
3837 12 Apr 16 nicklas 546   }
3837 12 Apr 16 nicklas 547   
3837 12 Apr 16 nicklas 548   /**
3837 12 Apr 16 nicklas 549     List all folders on the remote file server and add them to the
3837 12 Apr 16 nicklas 550     'remoteFolders' set.
3837 12 Apr 16 nicklas 551     @return The number of new folders loaded
3837 12 Apr 16 nicklas 552   */
3844 14 Apr 16 nicklas 553   public static int loadRemoteFolders(DbControl dc, Fileserver server, Set<RemoteFolder> remoteFolders)
3837 12 Apr 16 nicklas 554   {
3837 12 Apr 16 nicklas 555     int sizeBefore = remoteFolders.size();
3837 12 Apr 16 nicklas 556     
3837 12 Apr 16 nicklas 557     // Get the project archive and connect to it via SSH
3837 12 Apr 16 nicklas 558     FileServer fs = server.load(dc);
3837 12 Apr 16 nicklas 559     int fileServerId = fs.getId();
4306 17 Jan 17 nicklas 560     RemoteHost host = new RemoteHost(new ConnectionInfo(fs));
4306 17 Jan 17 nicklas 561     String rootPath = ScriptUtil.checkValidPath(fs.getRootPath(), true, true);
4306 17 Jan 17 nicklas 562     RemoteSession session = null;
3837 12 Apr 16 nicklas 563     try
3837 12 Apr 16 nicklas 564     {
3837 12 Apr 16 nicklas 565
4306 17 Jan 17 nicklas 566       session = host.connect(5);
3837 12 Apr 16 nicklas 567       // The 'find' command generate tab-separated output:
3839 13 Apr 16 nicklas 568       // 0: date+time in format 'yyyyMMdd HHmm'
3839 13 Apr 16 nicklas 569       // 1: Path with leading '/'  
3839 13 Apr 16 nicklas 570       // 2: Owner of the folder
3837 12 Apr 16 nicklas 571       
3839 13 Apr 16 nicklas 572       String findCmd = "find " + rootPath + " -type d -printf '%TY%Tm%Td %TH%TM\\t/%P\\t%u\\n'";
4306 17 Jan 17 nicklas 573       CmdResult<String> find = session.executeCmd(findCmd, 60);
4311 17 Jan 17 nicklas 574       find.throwExceptionIfNonZeroExitStatus();
3837 12 Apr 16 nicklas 575       
3837 12 Apr 16 nicklas 576       String[] lines = find.getStdout().split("\\n");
3837 12 Apr 16 nicklas 577       for (String line : lines)
3837 12 Apr 16 nicklas 578       {
3839 13 Apr 16 nicklas 579         String[] entry = line.split("\\t", 3);
3839 13 Apr 16 nicklas 580         if (entry.length < 3) continue;
3837 12 Apr 16 nicklas 581   
3837 12 Apr 16 nicklas 582         String path = entry[1];
3837 12 Apr 16 nicklas 583         // Get rid of path that we do not care about
3837 12 Apr 16 nicklas 584         if ("/".equals(path)) continue;
3837 12 Apr 16 nicklas 585         
3839 13 Apr 16 nicklas 586         remoteFolders.add(new RemoteFolder(path, entry[0], entry[2], fileServerId));
3837 12 Apr 16 nicklas 587       }
3837 12 Apr 16 nicklas 588     }
3837 12 Apr 16 nicklas 589     finally
3837 12 Apr 16 nicklas 590     {
4306 17 Jan 17 nicklas 591       OpenGrid.close(session);
3837 12 Apr 16 nicklas 592     }
3837 12 Apr 16 nicklas 593     
3837 12 Apr 16 nicklas 594     // Return the number of new folders added
3837 12 Apr 16 nicklas 595     return remoteFolders.size() - sizeBefore;
3837 12 Apr 16 nicklas 596   }
3837 12 Apr 16 nicklas 597   
3837 12 Apr 16 nicklas 598   /**
3844 14 Apr 16 nicklas 599     Filter the list with remote folders against the known folders and
3844 14 Apr 16 nicklas 600     return only the unkown, stray folders.
3844 14 Apr 16 nicklas 601   */
3844 14 Apr 16 nicklas 602   public static List<RemoteFolder> findStrayFolders(Collection<RemoteFolder> remoteFolders, Set<String> knownFolders)
3844 14 Apr 16 nicklas 603   {
3844 14 Apr 16 nicklas 604     List<RemoteFolder> strayFolders = new ArrayList<RemoteFolder>();
3844 14 Apr 16 nicklas 605     Set<String> strayPaths = new HashSet<String>();
3844 14 Apr 16 nicklas 606     for (RemoteFolder rf : remoteFolders)
3844 14 Apr 16 nicklas 607     {
3844 14 Apr 16 nicklas 608       String path = rf.getPath();
3844 14 Apr 16 nicklas 609       if (!knownFolders.contains(path))
3844 14 Apr 16 nicklas 610       {
3844 14 Apr 16 nicklas 611         boolean registerAsStray = strayPaths.add(path);
3844 14 Apr 16 nicklas 612         // Check if a parent folder is already a stray path
3844 14 Apr 16 nicklas 613         // We do not want to register child folders as stray
3844 14 Apr 16 nicklas 614         // For example if '/foo' and '/foo/bar' are stray
3844 14 Apr 16 nicklas 615         // only register '/foo'
3844 14 Apr 16 nicklas 616         int i;
3844 14 Apr 16 nicklas 617         while (registerAsStray && (i = path.lastIndexOf("/")) > 0)
3844 14 Apr 16 nicklas 618         {
3844 14 Apr 16 nicklas 619           path = path.substring(0, i);
3844 14 Apr 16 nicklas 620           registerAsStray = !strayPaths.contains(path);
3844 14 Apr 16 nicklas 621         }
3844 14 Apr 16 nicklas 622         if (registerAsStray) strayFolders.add(rf);
3844 14 Apr 16 nicklas 623       }
3844 14 Apr 16 nicklas 624     }
3844 14 Apr 16 nicklas 625     
3844 14 Apr 16 nicklas 626     return strayFolders;
3844 14 Apr 16 nicklas 627   }
3844 14 Apr 16 nicklas 628   
3844 14 Apr 16 nicklas 629   /**
3837 12 Apr 16 nicklas 630     Represents a remote folder on a file server.
3837 12 Apr 16 nicklas 631   */
3844 14 Apr 16 nicklas 632   public static class RemoteFolder
3837 12 Apr 16 nicklas 633     implements Comparable<RemoteFolder>
3837 12 Apr 16 nicklas 634   {
3837 12 Apr 16 nicklas 635     private final String path;
3838 13 Apr 16 nicklas 636     private final String lastModified;
3839 13 Apr 16 nicklas 637     private final String owner;
3837 12 Apr 16 nicklas 638     private final int fileServer;
3837 12 Apr 16 nicklas 639     
3839 13 Apr 16 nicklas 640     RemoteFolder(String path, String lastModified, String owner, int fileServer)
3837 12 Apr 16 nicklas 641     {
3837 12 Apr 16 nicklas 642       this.path = path;
3838 13 Apr 16 nicklas 643       this.lastModified = lastModified;
3839 13 Apr 16 nicklas 644       this.owner = owner;
3837 12 Apr 16 nicklas 645       this.fileServer = fileServer;
3837 12 Apr 16 nicklas 646     }
3837 12 Apr 16 nicklas 647     
3837 12 Apr 16 nicklas 648     public String getPath()
3837 12 Apr 16 nicklas 649     {
3837 12 Apr 16 nicklas 650       return path;
3837 12 Apr 16 nicklas 651     }
3837 12 Apr 16 nicklas 652     
3838 13 Apr 16 nicklas 653     public String getLastModified()
3837 12 Apr 16 nicklas 654     {
3838 13 Apr 16 nicklas 655       return lastModified;
3837 12 Apr 16 nicklas 656     }
3837 12 Apr 16 nicklas 657     
3839 13 Apr 16 nicklas 658     public String getOwner()
3839 13 Apr 16 nicklas 659     {
3839 13 Apr 16 nicklas 660       return owner;
3839 13 Apr 16 nicklas 661     }
3839 13 Apr 16 nicklas 662     
3837 12 Apr 16 nicklas 663     public int getFileServer()
3837 12 Apr 16 nicklas 664     {
3837 12 Apr 16 nicklas 665       return fileServer;
3837 12 Apr 16 nicklas 666     }
3837 12 Apr 16 nicklas 667   
3837 12 Apr 16 nicklas 668     JSONObject asJSONObject()
3837 12 Apr 16 nicklas 669     {
3837 12 Apr 16 nicklas 670       JSONObject json = new JSONObject();
3837 12 Apr 16 nicklas 671       json.put("path", path);
3838 13 Apr 16 nicklas 672       json.put("lastModified", lastModified);
3839 13 Apr 16 nicklas 673       json.put("owner", owner);
3837 12 Apr 16 nicklas 674       json.put("fileServer", fileServer);
3837 12 Apr 16 nicklas 675       return json;
3837 12 Apr 16 nicklas 676     }
3837 12 Apr 16 nicklas 677     
3837 12 Apr 16 nicklas 678     @Override
3837 12 Apr 16 nicklas 679     public boolean equals(Object obj) 
3837 12 Apr 16 nicklas 680     {
3837 12 Apr 16 nicklas 681       if (obj == null) return false;
3837 12 Apr 16 nicklas 682       if (obj.getClass() != this.getClass()) return false;
3837 12 Apr 16 nicklas 683       RemoteFolder o = (RemoteFolder)obj;
3837 12 Apr 16 nicklas 684       return path.equals(o.path) && fileServer == o.fileServer;
3837 12 Apr 16 nicklas 685     }
3837 12 Apr 16 nicklas 686
3837 12 Apr 16 nicklas 687     @Override
3837 12 Apr 16 nicklas 688     public int hashCode() 
3837 12 Apr 16 nicklas 689     {
3837 12 Apr 16 nicklas 690       return path.hashCode() + fileServer;
3837 12 Apr 16 nicklas 691     }
3837 12 Apr 16 nicklas 692
3837 12 Apr 16 nicklas 693     @Override
3837 12 Apr 16 nicklas 694     public String toString() 
3837 12 Apr 16 nicklas 695     {
3837 12 Apr 16 nicklas 696       return path;
3837 12 Apr 16 nicklas 697     }
3837 12 Apr 16 nicklas 698
3837 12 Apr 16 nicklas 699     @Override
3837 12 Apr 16 nicklas 700     public int compareTo(RemoteFolder o) 
3837 12 Apr 16 nicklas 701     {
3837 12 Apr 16 nicklas 702       if (fileServer != o.fileServer) return fileServer - o.fileServer;
3837 12 Apr 16 nicklas 703       return path.compareTo(o.path);
3837 12 Apr 16 nicklas 704     }
3837 12 Apr 16 nicklas 705     
3837 12 Apr 16 nicklas 706   }
3843 13 Apr 16 nicklas 707   
3843 13 Apr 16 nicklas 708   static class ConnectedHost
3843 13 Apr 16 nicklas 709     implements Closeable
3843 13 Apr 16 nicklas 710   {
3843 13 Apr 16 nicklas 711     final FileServer server;
4306 17 Jan 17 nicklas 712     final RemoteHost host;
4306 17 Jan 17 nicklas 713     final RemoteSession session;
3843 13 Apr 16 nicklas 714     
3843 13 Apr 16 nicklas 715     ConnectedHost(FileServer server)
3843 13 Apr 16 nicklas 716     {
3843 13 Apr 16 nicklas 717       this.server = server;
4306 17 Jan 17 nicklas 718       this.host = new RemoteHost(new ConnectionInfo(server));
4306 17 Jan 17 nicklas 719       this.session = host.connect(5);
3843 13 Apr 16 nicklas 720     }
3843 13 Apr 16 nicklas 721     
4306 17 Jan 17 nicklas 722     CmdResult<String> executeCmd(String cmd)
3843 13 Apr 16 nicklas 723     {
4306 17 Jan 17 nicklas 724       return session.executeCmd(cmd, 5);
3843 13 Apr 16 nicklas 725     }
3843 13 Apr 16 nicklas 726     
3843 13 Apr 16 nicklas 727     @Override
3843 13 Apr 16 nicklas 728     public void close() 
3843 13 Apr 16 nicklas 729       throws IOException 
3843 13 Apr 16 nicklas 730     {
4306 17 Jan 17 nicklas 731       OpenGrid.close(session);
3843 13 Apr 16 nicklas 732     }
3843 13 Apr 16 nicklas 733   }
5581 21 Aug 19 nicklas 734   
5581 21 Aug 19 nicklas 735   
5581 21 Aug 19 nicklas 736   /**
5581 21 Aug 19 nicklas 737     Transformer implementation that find file items that are either linked
5581 21 Aug 19 nicklas 738     via any-to-any links or file sets. 
5581 21 Aug 19 nicklas 739   */
5581 21 Aug 19 nicklas 740   static class ToFileTransformer
5581 21 Aug 19 nicklas 741     extends AbstractSourceItemTransformer
5581 21 Aug 19 nicklas 742   {
5581 21 Aug 19 nicklas 743
5581 21 Aug 19 nicklas 744     private final ItemQuery<File> anyQuery;
5581 21 Aug 19 nicklas 745     private final ItemQuery<File> fileSetQuery;
5581 21 Aug 19 nicklas 746     
5581 21 Aug 19 nicklas 747     protected ToFileTransformer(Item source) 
5581 21 Aug 19 nicklas 748     {
5581 21 Aug 19 nicklas 749       super(source, Item.FILE);
5581 21 Aug 19 nicklas 750       
5581 21 Aug 19 nicklas 751       // Find all files that are targeted by any-to-any-links from a given list of source items
5581 21 Aug 19 nicklas 752       String subquery = "SELECT at.toId FROM AnyToAnyData at" +
5581 21 Aug 19 nicklas 753           " WHERE at.toType = " + Item.FILE.getValue() + 
5581 21 Aug 19 nicklas 754           " AND at.fromType = " + source.getValue() +
5581 21 Aug 19 nicklas 755           " AND at.fromId IN (:items)";
5581 21 Aug 19 nicklas 756       anyQuery = File.getQuery();
5581 21 Aug 19 nicklas 757       anyQuery.restrict(Restrictions.in(
5581 21 Aug 19 nicklas 758         Hql.property("id"), 
5581 21 Aug 19 nicklas 759         Hql.expression(subquery, null)
5581 21 Aug 19 nicklas 760       ));
5581 21 Aug 19 nicklas 761       
5581 21 Aug 19 nicklas 762       // Find all files that are members of file-sets belonging to a given list of source items
5581 21 Aug 19 nicklas 763       subquery = "SELECT mbr.file.id FROM " + source.getDataClass().getSimpleName() + " src " +
5581 21 Aug 19 nicklas 764         " INNER JOIN src.fileSet fs " +
5581 21 Aug 19 nicklas 765         " INNER JOIN fs.members mbr "+
5581 21 Aug 19 nicklas 766         " WHERE src.id IN (:items)";
5581 21 Aug 19 nicklas 767       fileSetQuery = File.getQuery();
5581 21 Aug 19 nicklas 768       fileSetQuery.restrict(Restrictions.in(
5581 21 Aug 19 nicklas 769         Hql.property("id"), 
5581 21 Aug 19 nicklas 770         Hql.expression(subquery, null)
5581 21 Aug 19 nicklas 771       ));
5581 21 Aug 19 nicklas 772     }
5581 21 Aug 19 nicklas 773
5581 21 Aug 19 nicklas 774     @Override
5581 21 Aug 19 nicklas 775     public Set<Integer> transform(TransformContext ctx, Set<Integer> source) 
5581 21 Aug 19 nicklas 776     {
5581 21 Aug 19 nicklas 777       anyQuery.setIncludes(ctx.getInclude());
5581 21 Aug 19 nicklas 778       Set<Integer> files = safeIdList(ctx.getDbControl(), anyQuery, "items", source);
5581 21 Aug 19 nicklas 779       
5581 21 Aug 19 nicklas 780       fileSetQuery.setIncludes(ctx.getInclude());
5581 21 Aug 19 nicklas 781       files.addAll(safeIdList(ctx.getDbControl(), fileSetQuery, "items", source));
5581 21 Aug 19 nicklas 782       return files;
5581 21 Aug 19 nicklas 783     }
5581 21 Aug 19 nicklas 784     
5581 21 Aug 19 nicklas 785   }
5581 21 Aug 19 nicklas 786   
3837 12 Apr 16 nicklas 787 }