extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/plugins/release/JsonWriter.java

Code
Comments
Other
Rev Date Author Line
4346 10 Feb 17 nicklas 1 package net.sf.basedb.reggie.plugins.release;
4346 10 Feb 17 nicklas 2
4346 10 Feb 17 nicklas 3 import java.io.IOException;
4346 10 Feb 17 nicklas 4 import java.io.OutputStreamWriter;
4346 10 Feb 17 nicklas 5 import java.io.Writer;
4346 10 Feb 17 nicklas 6 import java.nio.charset.Charset;
4371 02 Mar 17 nicklas 7 import java.util.ArrayList;
7034 10 Feb 23 nicklas 8 import java.util.Comparator;
4365 27 Feb 17 nicklas 9 import java.util.List;
4466 25 Apr 17 nicklas 10 import java.util.Map;
7035 10 Feb 23 nicklas 11 import java.util.Queue;
7035 10 Feb 23 nicklas 12 import java.util.concurrent.ConcurrentLinkedQueue;
4346 10 Feb 17 nicklas 13
4346 10 Feb 17 nicklas 14 import org.json.simple.JSONArray;
4346 10 Feb 17 nicklas 15 import org.json.simple.JSONObject;
4346 10 Feb 17 nicklas 16
5089 14 Nov 18 nicklas 17 import net.sf.basedb.core.BioSource;
4346 10 Feb 17 nicklas 18 import net.sf.basedb.core.DbControl;
4365 27 Feb 17 nicklas 19 import net.sf.basedb.core.ItemList;
4346 10 Feb 17 nicklas 20 import net.sf.basedb.core.plugin.ExportOutputStream;
5091 14 Nov 18 nicklas 21 import net.sf.basedb.reggie.json.FilteredJSONArray;
4346 10 Feb 17 nicklas 22 import net.sf.basedb.util.FileUtil;
5091 14 Nov 18 nicklas 23 import net.sf.basedb.util.filter.NotNullFilter;
4346 10 Feb 17 nicklas 24
4346 10 Feb 17 nicklas 25 /**
4346 10 Feb 17 nicklas 26   A special writer implementation that writes a single JSON data file
4346 10 Feb 17 nicklas 27   for each cohort item.
4346 10 Feb 17 nicklas 28   
4346 10 Feb 17 nicklas 29   @author nicklas
4346 10 Feb 17 nicklas 30   @since 4.10
4346 10 Feb 17 nicklas 31 */
4346 10 Feb 17 nicklas 32 public class JsonWriter 
4346 10 Feb 17 nicklas 33 {
4346 10 Feb 17 nicklas 34
5089 14 Nov 18 nicklas 35   private final ReleaseWriterOptions options;
4346 10 Feb 17 nicklas 36   private final OutputLocation location;
4371 02 Mar 17 nicklas 37   private final List<CohortWriter> itemWriters;
4382 07 Mar 17 nicklas 38   private final JSONArray jsonFiles;
7035 10 Feb 23 nicklas 39   private final Queue<QueuedFile> fileQueue;
4346 10 Feb 17 nicklas 40   
4346 10 Feb 17 nicklas 41   public JsonWriter(DbControl dc, OutputLocation location, ReleaseWriterOptions options) 
4346 10 Feb 17 nicklas 42   {
5089 14 Nov 18 nicklas 43     this.options = options;
4346 10 Feb 17 nicklas 44     this.location = location;
4371 02 Mar 17 nicklas 45     this.itemWriters = new ArrayList<>();
4382 07 Mar 17 nicklas 46     this.jsonFiles = new JSONArray();
7035 10 Feb 23 nicklas 47     this.fileQueue = new ConcurrentLinkedQueue<>();
4346 10 Feb 17 nicklas 48   }
4346 10 Feb 17 nicklas 49   
4371 02 Mar 17 nicklas 50   /**
4371 02 Mar 17 nicklas 51     Register the given cohort writer with this JSON writer.
4371 02 Mar 17 nicklas 52   */
4371 02 Mar 17 nicklas 53   public void registerItemWriter(CohortWriter cw)
4371 02 Mar 17 nicklas 54   {
4371 02 Mar 17 nicklas 55     itemWriters.add(cw);
4371 02 Mar 17 nicklas 56   }
4371 02 Mar 17 nicklas 57
5089 14 Nov 18 nicklas 58   public void writeIndex(ItemList list, List<BioSource> biosources)
4365 27 Feb 17 nicklas 59   {
4365 27 Feb 17 nicklas 60     ExportOutputStream out = null;
4365 27 Feb 17 nicklas 61     try
4365 27 Feb 17 nicklas 62     {
4427 27 Mar 17 nicklas 63       out = location.getOutputStream("/index.json", false);
4365 27 Feb 17 nicklas 64       out.setCharacterSet("UTF-8");
4365 27 Feb 17 nicklas 65       out.setMimeType("application/json");
4365 27 Feb 17 nicklas 66
4365 27 Feb 17 nicklas 67       Writer writer = new OutputStreamWriter(out, Charset.forName("UTF-8"));
4420 23 Mar 17 nicklas 68       JSONObject json = new JSONObject();
4420 23 Mar 17 nicklas 69       
4420 23 Mar 17 nicklas 70       JSONObject jsonRelease = new JSONObject();
5089 14 Nov 18 nicklas 71       jsonRelease.put("version", options.getVersion());
5089 14 Nov 18 nicklas 72       jsonRelease.put("useExternalId", true);
4420 23 Mar 17 nicklas 73       json.put("release", jsonRelease);
4420 23 Mar 17 nicklas 74       
4365 27 Feb 17 nicklas 75       JSONObject jsonList = new JSONObject();
4365 27 Feb 17 nicklas 76       jsonList.put("name", list.getName());
4365 27 Feb 17 nicklas 77       jsonList.put("size", list.getSize());
4365 27 Feb 17 nicklas 78       json.put("list", jsonList);
4378 03 Mar 17 nicklas 79       json.writeJSONString(writer);
4365 27 Feb 17 nicklas 80       
4378 03 Mar 17 nicklas 81       writer.flush();
4378 03 Mar 17 nicklas 82       out.flush();
4378 03 Mar 17 nicklas 83       writer.close();
4378 03 Mar 17 nicklas 84     }
4378 03 Mar 17 nicklas 85     catch (IOException ex)
4378 03 Mar 17 nicklas 86     {
4378 03 Mar 17 nicklas 87       throw new RuntimeException(ex);
4378 03 Mar 17 nicklas 88     }
4378 03 Mar 17 nicklas 89     finally
4378 03 Mar 17 nicklas 90     {
4378 03 Mar 17 nicklas 91       FileUtil.close(out);
4378 03 Mar 17 nicklas 92     }  
4378 03 Mar 17 nicklas 93   }
4378 03 Mar 17 nicklas 94   
4408 20 Mar 17 nicklas 95   public void writeTypeDefs()
4378 03 Mar 17 nicklas 96   {
4378 03 Mar 17 nicklas 97     ExportOutputStream out = null;
4378 03 Mar 17 nicklas 98     try
4378 03 Mar 17 nicklas 99     {
4427 27 Mar 17 nicklas 100       out = location.getOutputStream("/typedefs.json", false);
4378 03 Mar 17 nicklas 101       out.setCharacterSet("UTF-8");
4378 03 Mar 17 nicklas 102       out.setMimeType("application/json");
4378 03 Mar 17 nicklas 103
4378 03 Mar 17 nicklas 104       Writer writer = new OutputStreamWriter(out, Charset.forName("UTF-8"));
4378 03 Mar 17 nicklas 105       JSONArray json = new JSONArray();
4378 03 Mar 17 nicklas 106       
4378 03 Mar 17 nicklas 107       for (CohortWriter cw : itemWriters)
4378 03 Mar 17 nicklas 108       {
4469 26 Apr 17 nicklas 109         for (CohortTypeDef cdef : cw.getTypeDefsInJSON())
4378 03 Mar 17 nicklas 110         {
4469 26 Apr 17 nicklas 111           json.add(cdef.toJSONObject());
4378 03 Mar 17 nicklas 112         }
4378 03 Mar 17 nicklas 113       }
4378 03 Mar 17 nicklas 114       
4365 27 Feb 17 nicklas 115       json.writeJSONString(writer);
4365 27 Feb 17 nicklas 116       
4365 27 Feb 17 nicklas 117       writer.flush();
4365 27 Feb 17 nicklas 118       out.flush();
4365 27 Feb 17 nicklas 119       writer.close();
4365 27 Feb 17 nicklas 120     }
4365 27 Feb 17 nicklas 121     catch (IOException ex)
4365 27 Feb 17 nicklas 122     {
4365 27 Feb 17 nicklas 123       throw new RuntimeException(ex);
4365 27 Feb 17 nicklas 124     }
4365 27 Feb 17 nicklas 125     finally
4365 27 Feb 17 nicklas 126     {
4365 27 Feb 17 nicklas 127       FileUtil.close(out);
4378 03 Mar 17 nicklas 128     }  
4365 27 Feb 17 nicklas 129   }
4378 03 Mar 17 nicklas 130
4552 04 Jul 17 nicklas 131   public void writeJsonData(CohortItem item) 
4552 04 Jul 17 nicklas 132   {
7022 06 Feb 23 nicklas 133     // This method may be called by multiple threads
7022 06 Feb 23 nicklas 134     // The CohortWriter implementations are assumed to be thread-safe
7035 10 Feb 23 nicklas 135     QueuedFile file = new QueuedFile(item.getName());
4371 02 Mar 17 nicklas 136     for (CohortWriter cw : itemWriters)
4371 02 Mar 17 nicklas 137     {
7035 10 Feb 23 nicklas 138       file.json.addAll(cw.toJSONObjects(item));
4371 02 Mar 17 nicklas 139     }
7035 10 Feb 23 nicklas 140     // Add to the file queue. The files are written by the main thread
7035 10 Feb 23 nicklas 141     // in writeQueuedJsonFiles() since the OutputLocaction implementation
7035 10 Feb 23 nicklas 142     // may not be thread-safe
7035 10 Feb 23 nicklas 143     fileQueue.add(file);
7035 10 Feb 23 nicklas 144   }
7035 10 Feb 23 nicklas 145   
7035 10 Feb 23 nicklas 146   /**
7035 10 Feb 23 nicklas 147     Write all queued file data to the output location.
7035 10 Feb 23 nicklas 148     This method is intended to be called by the main thread
7035 10 Feb 23 nicklas 149     only and will write the files that are in the queue at
7035 10 Feb 23 nicklas 150     the entry of the method. The exporter threads may add
7035 10 Feb 23 nicklas 151     more files to the queue while this method is executing
7035 10 Feb 23 nicklas 152     but those files have to wait until the next time. 
7035 10 Feb 23 nicklas 153     
7035 10 Feb 23 nicklas 154     To ensure that all files are written this method should be
7035 10 Feb 23 nicklas 155     called at least once when all exporter threads have finished.
7035 10 Feb 23 nicklas 156   */
7035 10 Feb 23 nicklas 157   public void writeQueuedJsonFiles()
7035 10 Feb 23 nicklas 158   {
7035 10 Feb 23 nicklas 159     int maxToWrite = fileQueue.size();
7035 10 Feb 23 nicklas 160     int numWritten = 0;
7035 10 Feb 23 nicklas 161     while (numWritten < maxToWrite)
4346 10 Feb 17 nicklas 162     {
7035 10 Feb 23 nicklas 163       QueuedFile file = fileQueue.poll();
7035 10 Feb 23 nicklas 164       if (file == null) break;
7035 10 Feb 23 nicklas 165       
7022 06 Feb 23 nicklas 166       ExportOutputStream out = null;
7022 06 Feb 23 nicklas 167       try
7022 06 Feb 23 nicklas 168       {
7035 10 Feb 23 nicklas 169         out = location.getOutputStream(file.filename, false);
7022 06 Feb 23 nicklas 170         out.setCharacterSet("UTF-8");
7022 06 Feb 23 nicklas 171         out.setMimeType("application/json");
7022 06 Feb 23 nicklas 172   
7022 06 Feb 23 nicklas 173         Writer writer = new OutputStreamWriter(out, Charset.forName("UTF-8"));
7035 10 Feb 23 nicklas 174         file.json.writeJSONString(writer);
7022 06 Feb 23 nicklas 175         writer.flush();
7022 06 Feb 23 nicklas 176         out.flush();
7022 06 Feb 23 nicklas 177         writer.close();
7035 10 Feb 23 nicklas 178         jsonFiles.add(file.filename);
7035 10 Feb 23 nicklas 179         numWritten++;
7022 06 Feb 23 nicklas 180       }
7022 06 Feb 23 nicklas 181       catch (IOException ex)
7022 06 Feb 23 nicklas 182       {
7022 06 Feb 23 nicklas 183         throw new RuntimeException(ex);
7022 06 Feb 23 nicklas 184       }
7022 06 Feb 23 nicklas 185       finally
7022 06 Feb 23 nicklas 186       {
7022 06 Feb 23 nicklas 187         FileUtil.close(out);
7022 06 Feb 23 nicklas 188       }
4346 10 Feb 17 nicklas 189     }
4346 10 Feb 17 nicklas 190   }
4346 10 Feb 17 nicklas 191
7034 10 Feb 23 nicklas 192   @SuppressWarnings({ "unchecked", "rawtypes" })
4382 07 Mar 17 nicklas 193   public void writeFiles()
4382 07 Mar 17 nicklas 194   {
4382 07 Mar 17 nicklas 195     ExportOutputStream out = null;
4382 07 Mar 17 nicklas 196     try
4382 07 Mar 17 nicklas 197     {
7034 10 Feb 23 nicklas 198       jsonFiles.sort((Comparator)Comparator.naturalOrder());
4427 27 Mar 17 nicklas 199       out = location.getOutputStream("/files.json", false);
4382 07 Mar 17 nicklas 200       out.setCharacterSet("UTF-8");
4382 07 Mar 17 nicklas 201       out.setMimeType("application/json");
4371 02 Mar 17 nicklas 202
4382 07 Mar 17 nicklas 203       Writer writer = new OutputStreamWriter(out, Charset.forName("UTF-8"));
4382 07 Mar 17 nicklas 204       jsonFiles.writeJSONString(writer);
4382 07 Mar 17 nicklas 205       writer.flush();
4382 07 Mar 17 nicklas 206       out.flush();
4382 07 Mar 17 nicklas 207       writer.close();
4382 07 Mar 17 nicklas 208     }
4382 07 Mar 17 nicklas 209     catch (IOException ex)
4382 07 Mar 17 nicklas 210     {
4382 07 Mar 17 nicklas 211       throw new RuntimeException(ex);
4382 07 Mar 17 nicklas 212     }
4382 07 Mar 17 nicklas 213     finally
4382 07 Mar 17 nicklas 214     {
4382 07 Mar 17 nicklas 215       FileUtil.close(out);
4382 07 Mar 17 nicklas 216     }
4382 07 Mar 17 nicklas 217
4382 07 Mar 17 nicklas 218   }
4466 25 Apr 17 nicklas 219   
4466 25 Apr 17 nicklas 220   /**
4466 25 Apr 17 nicklas 221     Writes all batch index proxies to a JSON file. The file contains a
4466 25 Apr 17 nicklas 222     JSON Object which maps batch names and proxies to index values.
4466 25 Apr 17 nicklas 223           
4466 25 Apr 17 nicklas 224      Example:
4466 25 Apr 17 nicklas 225      {
4466 25 Apr 17 nicklas 226       "PartitionBatchNo": {
4466 25 Apr 17 nicklas 227         "28b6805f-1cc7-44bd-b6ff-3726a37dbeb1": 1,
4466 25 Apr 17 nicklas 228         "73c7548e-1f2f-47a3-8ffb-1e9288932b6c": 2
4466 25 Apr 17 nicklas 229       }
4466 25 Apr 17 nicklas 230     }
4466 25 Apr 17 nicklas 231   */
4466 25 Apr 17 nicklas 232   public void writeBatchIndexLookupFiles(Map<String, Map<String, String>> batchIndexMap)
4466 25 Apr 17 nicklas 233   {
4466 25 Apr 17 nicklas 234     JSONObject jsonLookups = new JSONObject();
4466 25 Apr 17 nicklas 235     
4466 25 Apr 17 nicklas 236     for (Map.Entry<String, Map<String, String>> entry : batchIndexMap.entrySet())
4466 25 Apr 17 nicklas 237     {
4466 25 Apr 17 nicklas 238       String batchName = entry.getKey();
4466 25 Apr 17 nicklas 239       Map<String, String> indexes = entry.getValue();
4466 25 Apr 17 nicklas 240       
4466 25 Apr 17 nicklas 241       JSONObject jsonValues = new JSONObject();
4466 25 Apr 17 nicklas 242       jsonLookups.put(batchName, jsonValues);
4466 25 Apr 17 nicklas 243       
4466 25 Apr 17 nicklas 244       int index = 1;
4466 25 Apr 17 nicklas 245       for (String proxy : indexes.values())
4466 25 Apr 17 nicklas 246       {
4466 25 Apr 17 nicklas 247         jsonValues.put(proxy, index);
4466 25 Apr 17 nicklas 248         index++;
4466 25 Apr 17 nicklas 249       }
4466 25 Apr 17 nicklas 250     }
4466 25 Apr 17 nicklas 251     
4466 25 Apr 17 nicklas 252     ExportOutputStream out = null;
4466 25 Apr 17 nicklas 253     try
4466 25 Apr 17 nicklas 254     {
4466 25 Apr 17 nicklas 255       out = location.getOutputStream("/batch-index-lookup.json", false);
4466 25 Apr 17 nicklas 256       out.setCharacterSet("UTF-8");
4466 25 Apr 17 nicklas 257       out.setMimeType("application/json");
4466 25 Apr 17 nicklas 258
4466 25 Apr 17 nicklas 259       Writer writer = new OutputStreamWriter(out, Charset.forName("UTF-8"));
4466 25 Apr 17 nicklas 260       jsonLookups.writeJSONString(writer);
4466 25 Apr 17 nicklas 261       writer.flush();
4466 25 Apr 17 nicklas 262       out.flush();
4466 25 Apr 17 nicklas 263       writer.close();
4466 25 Apr 17 nicklas 264     }
4466 25 Apr 17 nicklas 265     catch (IOException ex)
4466 25 Apr 17 nicklas 266     {
4466 25 Apr 17 nicklas 267       throw new RuntimeException(ex);
4466 25 Apr 17 nicklas 268     }
4466 25 Apr 17 nicklas 269     finally
4466 25 Apr 17 nicklas 270     {
4466 25 Apr 17 nicklas 271       FileUtil.close(out);
4466 25 Apr 17 nicklas 272     }
4466 25 Apr 17 nicklas 273     
4466 25 Apr 17 nicklas 274   }
4552 04 Jul 17 nicklas 275
7035 10 Feb 23 nicklas 276   /**
7035 10 Feb 23 nicklas 277     A file waiting to be writted to the output location.
7035 10 Feb 23 nicklas 278   */
7035 10 Feb 23 nicklas 279   static class QueuedFile
7035 10 Feb 23 nicklas 280   {
7035 10 Feb 23 nicklas 281     final String filename;
7035 10 Feb 23 nicklas 282     final JSONArray json;
7035 10 Feb 23 nicklas 283     QueuedFile(String itemName)
7035 10 Feb 23 nicklas 284     {
7035 10 Feb 23 nicklas 285       this.filename = "/json/"+itemName+".json";
7035 10 Feb 23 nicklas 286       this.json =  new FilteredJSONArray(new NotNullFilter<>(false));
7035 10 Feb 23 nicklas 287     }
7035 10 Feb 23 nicklas 288   }
7035 10 Feb 23 nicklas 289   
4346 10 Feb 17 nicklas 290 }