1. Kevin Archie
  2. UploadAssistant

Commits

Kevin A. Archie  committed f8d109a

Fix handling of config-based anon scripts

  • Participants
  • Parent commits 8b456e9
  • Branches default

Comments (0)

Files changed (6)

File src/main/java/org/nrg/dcm/Study.java

View file
             	protocol = ((SessionVariable) params.get(SessionVariableNames.PROTOCOL_LABEL)).getValue();
             }
             
-            // See if we're applying a metadata modification script. If so, any parameters
+            // See if we're applying any metadata modification scripts. If so, any parameters
             // we're sending in the manifest should be the post-modification values.
-            final ScriptApplicator applicator;
+            final Iterable<ScriptApplicator> applicators;
             try {
-                applicator = project.getDicomScriptApplicator();
+                applicators = project.getDicomScriptApplicators();
             } catch (RuntimeException exception) {
                 logger.error("problem retrieving script applicator", exception);
                 Analytics.enter(UploadAssistantApplet.class, "Error retrieving script applicator", exception);
             final UploadStatisticsReporter stats = new UploadStatisticsReporter(progress);
             for (final Series s : uploads) {
                 stats.addToSend(s.getSize());
-                final ZipSeriesUploader uploader = new ZipSeriesUploader(dataPostURL, useFixedSize, s, applicator, stats, jsessionidCookie);
+                final ZipSeriesUploader uploader = new ZipSeriesUploader(dataPostURL, useFixedSize, s, applicators, stats, jsessionidCookie);
                 uploaders.put(completionService.submit(uploader), uploader);
             }
 
      */
     public List<SessionVariable> getVariables(final Map<?, ?> params) {
         final Project project = ((Project) params.get(SelectProjectPage.PRODUCT_NAME));
-        final List<Variable> dvs;
+        final List<Variable> dvs = Lists.newArrayList();
         try {
-            final ScriptApplicator applicator = project.getDicomScriptApplicator();
-            if (null == applicator) {
-                logger.debug("no script available");
-                return Collections.emptyList();
-            } else {
-                dvs = applicator.getSortedVariables();
+            // TODO: this is a little inadequate; it repeats similarly-named variables from
+            // different scripts. Better would be some sort of cross-script merge.
+            final Iterable<ScriptApplicator> applicators = project.getDicomScriptApplicators();
+            for (final ScriptApplicator a : applicators) {
+                dvs.addAll(a.getSortedVariables());
             }
         } catch (Throwable t) {
             logger.warn("unable to load script", t);

File src/main/java/org/nrg/io/dcm/ZipSeriesUploader.java

View file
     private final Logger logger = LoggerFactory.getLogger(ZipSeriesUploader.class);
     private final URL url;
     private final Series series;
-    private final ScriptApplicator applicator;
+    private final Iterable<ScriptApplicator> applicators;
     private final UploadStatisticsReporter progress;
     private final boolean useFixedSizeStreaming;
     private final JSESSIONIDCookie jsessionidCookie;
     public ZipSeriesUploader(final URL url,
             final boolean useFixedSizeStreaming,
             final Series series,
-            final ScriptApplicator applicator,
+            final Iterable<ScriptApplicator> applicators,
             final UploadStatisticsReporter progress,
             final JSESSIONIDCookie jsessionidCookie) {
         this.url = url;
         this.useFixedSizeStreaming = useFixedSizeStreaming;
         this.series = series;
-        this.applicator = applicator;
+        this.applicators = applicators;
         this.progress = progress;
         this.jsessionidCookie = jsessionidCookie;
     }
     }
 
     private int getTopTag() {
-        return Math.max(applicator.getTopTag(), Tag.SOPInstanceUID);
+        int top = Tag.SOPInstanceUID;
+        for (final ScriptApplicator a : applicators) {
+            final int atop = a.getTopTag();
+            if (atop > top) {
+                top = atop;
+            }
+        }
+        return top;
     }
 
     private void addFileToZip(final File f, final ZipOutputStream zos, final DicomInputHandler handler)
             try {
                 dis.setHandler(handler);
                 final DicomObject o = dis.readDicomObject();
-                applicator.apply(f, o);
+                for (final ScriptApplicator a : applicators) {
+                    a.apply(f, o);
+                }
+                @SuppressWarnings("resource")
                 final DicomOutputStream dos = new DicomOutputStream(zos);
                 dos.setAutoFinish(false);
                 final String tsuid = o.getString(Tag.TransferSyntaxUID, UID.ImplicitVRLittleEndian);
             try {
                 bis.close();
             } catch (IOException e) {
-                throw ioexception = (null == ioexception) ? e : ioexception;
+                if (null == ioexception) {
+                    ioexception = e;
+                } else {
+                    logger.error("error closing stream buffer", e);
+                }
+            }
+            try {
+                fin.close();
+            } catch (IOException e) {
+                if (null == ioexception) {
+                    ioexception = e;
+                } else {
+                    logger.error("error closing input DICOM file", e);
+                }
+            }
+            if (null != ioexception) {
+                throw ioexception;
             }
         }
 

File src/main/java/org/nrg/net/xnat/BaseScriptApplicatorRetreiver.java

View file
 /**
- * Copyright (c) 2010 Washington University
+ * Copyright (c) 2010,2012 Washington University
  */
 package org.nrg.net.xnat;
 
 import java.io.InputStream;
 import java.net.HttpURLConnection;
-import java.util.Arrays;
-import java.util.Collection;
 import java.util.concurrent.Callable;
 
 import org.nrg.net.HttpURLConnectionProcessor;
 import org.nrg.net.RestServer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * @author Kevin A. Archie <karchie@wustl.edu>
  *
  */
-class BaseScriptApplicatorRetreiver<T> implements Callable<T> {
-    private final Logger logger = LoggerFactory.getLogger(BaseScriptApplicatorRetreiver.class);
+class BaseScriptApplicatorRetreiver<ApplicatorT> implements Callable<ApplicatorT> {
     private final RestServer xnat;
-    private final Collection<String> uris;
-    private final ScriptApplicatorFactory<T> factory;
-    private final T defaultApplicator;
+    private final String path;
+    private final ScriptApplicatorFactory<ApplicatorT> factory;
 
-    protected static interface ScriptApplicatorFactory<T> {
-        T createScriptApplicator(final InputStream in) throws Exception;
+    public static interface ScriptApplicatorFactory<A> {
+        A createScriptApplicator(final InputStream in) throws Exception;
     }
 
     BaseScriptApplicatorRetreiver(final RestServer xnat,
-            final ScriptApplicatorFactory<T> factory,
-            final String defaultResourcePath,
-            final String...uris) {
+            final ScriptApplicatorFactory<ApplicatorT> factory,
+            final String path) {
         this.xnat = xnat;
         this.factory = factory;
-        this.uris = Arrays.asList(uris);
-
-        T da = null;
-        if (null != defaultResourcePath) {
-            try {
-                da = getApplicator(factory, defaultResourcePath);
-            } catch (Throwable t) {
-                logger.error("Unable to load global default script " + defaultResourcePath, t);
-            }
-        }
-        if (null == da) {
-            try {
-                da = factory.createScriptApplicator(null);
-            } catch (RuntimeException e) {
-                throw e;
-            } catch (Exception e) {
-                throw new RuntimeException(e);
-            }
-        }
-        this.defaultApplicator = da;
+        this.path = path;
     }
 
     /*
      * (non-Javadoc)
      * @see java.util.concurrent.Callable#call()
      */
-    public final T call() throws Exception {
-        final ConnectionProcessor processor = new ConnectionProcessor(factory);
-        T applicator = null;
-        for (final String uri : uris) {
-            try {
-                xnat.doGet(uri, processor);
-                applicator = processor.getApplicator();
-                if (null != applicator) {
-                    return applicator;
-                }
-                return processor.getApplicator();
-            } catch (Throwable t) {
-                logger.debug("unable to load script applicator from " + uri, t);
-            }
-        }
-        assert null == applicator;
-        return defaultApplicator;
+    public final ApplicatorT call() throws Exception {
+        final ConnectionProcessor<ApplicatorT> processor = new ConnectionProcessor<ApplicatorT>(factory);
+        xnat.doGet(path, processor);
+        return processor.getApplicator();
     }
 
 
-    private final class ConnectionProcessor implements HttpURLConnectionProcessor {
-        private final ScriptApplicatorFactory<T> factory;
-        private T applicator = null;
+    public static final class ConnectionProcessor<ApplicatorT> implements HttpURLConnectionProcessor {
+        private final ScriptApplicatorFactory<ApplicatorT> factory;
+        private ApplicatorT applicator = null;
 
-        ConnectionProcessor(final ScriptApplicatorFactory<T> factory) {
+        public ConnectionProcessor(final ScriptApplicatorFactory<ApplicatorT> factory) {
             this.factory = factory;
         }
 
             applicator = factory.createScriptApplicator(c.getInputStream());
         }
 
-        public T getApplicator() { return applicator; }
+        public ApplicatorT getApplicator() { return applicator; }
     }
 
 
      * @return applicator built from the named script
      * @throws Exception
      */
-    final T getApplicator(final ScriptApplicatorFactory<T> factory, final String resourcePath)
+    public static final <ApplicatorT> ApplicatorT getApplicator(final ScriptApplicatorFactory<ApplicatorT> factory, final String resourcePath)
     throws Exception {
         final InputStream in = BaseScriptApplicatorRetreiver.class.getResourceAsStream(resourcePath);
         if (null == in) {

File src/main/java/org/nrg/net/xnat/DicomScriptApplicatorRetriever.java

View file
 /**
- * Copyright (c) 2009-2011 Washington University
+ * Copyright (c) 2009-2012 Washington University
  */
 package org.nrg.net.xnat;
 
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.Collection;
+import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Callable;
 
 import org.nrg.dcm.edit.ScriptEvaluationException;
 import org.nrg.dcm.edit.ScriptFunction;
 import org.nrg.net.RestServer;
+import org.nrg.net.xnat.BaseScriptApplicatorRetreiver.ConnectionProcessor;
+import org.nrg.net.xnat.BaseScriptApplicatorRetreiver.ScriptApplicatorFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Lists;
 
 /**
  * @author Kevin A. Archie <karchie@wustl.edu>
  *
  */
 public final class DicomScriptApplicatorRetriever
-extends BaseScriptApplicatorRetreiver<ScriptApplicator>
-implements Callable<ScriptApplicator> {
+implements Callable<Iterable<ScriptApplicator>> {
+    private static final String sitePath = "/data/config/anon/script?contents=true";
+
+    private final Logger logger = LoggerFactory.getLogger(DicomScriptApplicatorRetriever.class);
+    private final RestServer xnat;
+    private final String project, projBasePath;
+    private final ScriptApplicatorFactory<ScriptApplicator> factory;
+
     public DicomScriptApplicatorRetriever(final RestServer xnat, final String project,
             final Map<String, ScriptFunction> scriptFunctions) {
-        super(xnat, buildFactory(scriptFunctions),
-              "/data/projects/" + project + "/config/anon/script?contents=true",
-              "/data/config/anon/script?contents=true");
+        this.xnat = xnat;
+        this.project = project;
+        this.projBasePath = "/data/config/edit/projects/" + project + "/image/dicom/";
+        this.factory = buildFactory(scriptFunctions);
+
     }
 
+    // site and project anon scripts are not isomorphic
+    // site: /data/config/anon/script?contents=true
+    // project: enabled/disabled: /data/config/edit/projects/PROJECT/image/dicom/status (key: edit)
+    //          script contents:  /data/config/edit/projects/PROJECT/image/dicom/script (key: script)
+
     private static ScriptApplicatorFactory<ScriptApplicator>
     buildFactory(final Map<String, ScriptFunction> scriptFunctions) {
         return new ScriptApplicatorFactory<ScriptApplicator>() {
             public ScriptApplicator createScriptApplicator(final InputStream in)
-            throws IOException,ScriptEvaluationException {
+                    throws IOException,ScriptEvaluationException {
                 return new ScriptApplicator(in, scriptFunctions);
             }
         };
     }
+
+
+    /*
+     * (non-Javadoc)
+     * @see java.util.concurrent.Callable#call()
+     */
+    public final Iterable<ScriptApplicator> call() throws Exception {
+        final List<ScriptApplicator> applicators = Lists.newArrayList();
+
+        // The site script is straightforward.
+        final ConnectionProcessor<ScriptApplicator> textProcessor = new ConnectionProcessor<ScriptApplicator>(factory);
+        xnat.doGet(sitePath, textProcessor);
+        final ScriptApplicator siteScript = textProcessor.getApplicator();
+        if (null != siteScript && !siteScript.getStatements().isEmpty()) {
+            applicators.add(siteScript);
+        }
+
+        // The project scripts are sort of complicated.
+        Collection<?> statusc = xnat.getValues(projBasePath + "status", "edit");
+        logger.trace("project {} script status: {}", project, statusc);
+        if (statusc.contains("true")) {
+            Collection<?> scriptsc = xnat.getValues(projBasePath + "script", "script");
+            logger.trace("project {} script text: {}", project, scriptsc);
+            for (final Object scripto : scriptsc) {
+                if (null == scripto) continue;
+                final ByteArrayInputStream bais = new ByteArrayInputStream(scripto.toString().getBytes("UTF-8"));
+                try {
+                    final ScriptApplicator projScript = factory.createScriptApplicator(bais);
+                    if (null != projScript && !projScript.getStatements().isEmpty()) {
+                        applicators.add(projScript);
+                    }
+                } finally {
+                    bais.close();
+                }
+            }
+        }
+        return applicators;
+    }
 }

File src/main/java/org/nrg/net/xnat/ECATScriptApplicatorRetriever.java

View file
 	public ECATScriptApplicatorRetriever(final RestServer xnat, final String project,
 			final Map<String,? extends ScriptFunction> scriptFunctions) {
 		super(xnat, buildFactory(scriptFunctions),
-				null,	// no default script
 				"/REST/projects/" + project + "/resources/UPLOAD_CONFIG/files/ecat.eas");
 	}
 	

File src/main/java/org/nrg/upload/data/Project.java

View file
 	private final Future<Map<String,String>> subjects;
 	private final Set<Subject> newSubjects = Sets.newLinkedHashSet();	// locally added subjects
 	private final Future<Map<String,String>> sessions;
-	private final Future<org.nrg.dcm.edit.ScriptApplicator> dicomScriptApplicator;
+	private final Future<Iterable<org.nrg.dcm.edit.ScriptApplicator>> dicomScriptApplicator;
 	private final Future<org.nrg.ecat.edit.ScriptApplicator> ecatScriptApplicator;
     private final Future<PrearchiveCode> prearchiveCode;
 
 		return sessions.get();
 	}
 
-	public org.nrg.dcm.edit.ScriptApplicator getDicomScriptApplicator()
+	public Iterable<org.nrg.dcm.edit.ScriptApplicator> getDicomScriptApplicators()
 	throws InterruptedException,ExecutionException {
 		return dicomScriptApplicator.get();
 	}