/** Run CWDataBrowserReset */ void runCWDataBrowserReset() { // is there already a reset thread? if (resetThread != null) { String2.log(String2.ERROR + " in runCWDataBrowserReset: resetThread!=null"); return; } // create a lower priority thread and run cwDataBrowserReset timeOfLastReset = System.currentTimeMillis(); cwDataBrowserReset = new CWDataBrowserReset(); resetThread = new Thread(cwDataBrowserReset); resetThread.setPriority(Thread.currentThread().getPriority() - 2); // -2 because some adjacent priorities map to the same OS priority resetThread.start(); }
/** * This gets the data from CWDataBrowserReset (if any is available) * * @return true if reset info was successfully retrieved */ public boolean getDataFromReset() { // is there no resetThread? if (resetThread == null) return false; // is the resetThread still running? if (resetThread.isAlive()) return false; // did the resetThread throw an exception? String2.log(cwDataBrowserReset.runInfo.toString()); if (cwDataBrowserReset.runError.length() > 0) { // error already printed to Tomcat's log // there is nothing more to be done // keep using old data // send email to Bob Simons? cwDataBrowserReset = null; resetThread = null; return false; } // store dataSet info activeDataSetOptions = cwDataBrowserReset.activeDataSetOptions; activeDataSetTitles = cwDataBrowserReset.activeDataSetTitles; activeDataSetContents = cwDataBrowserReset.activeDataSetContents; dataSet.setOptions(activeDataSetOptions); // 1 time only; doesn't change till next reset() dataSet.setTitles(activeDataSetTitles); // 1 time only; doesn't change till next reset() if (verbose) String2.log("activeDataSetTitles: " + String2.toNewlineString(activeDataSetTitles)); // print lots of useful information String2.log( "\n" + String2.makeString('*', 80) + "\nCWDataBrowser.getDataFromReset " + Calendar2.getCurrentISODateTimeStringLocal()); String2.log("CWDataBrowser construction was at " + constructorDateTime + ". Since then...\n"); String2.log("Data files found which have matching .gif files:"); String2.log(getUsageStatistics()); String2.log(" number of page requests initiated since construction: " + nRequestsInitiated); String2.log(" number of page requests completed since construction: " + nRequestsCompleted); if (nRequestsInitiated > 0) { DecimalFormat percent = new DecimalFormat("##0.000"); double nRequests = nRequestsInitiated / 100.0; String2.log("Data Set Usage:"); for (int i = 0; i < dataSetOptions.length; i++) String2.log( String2.right(percent.format(dataSetRequests[i] / nRequests), 9) + "% were for " + dataSetOptions[i]); String2.log("Time Period Usage:"); for (int i = 0; i < timePeriodOptions.length; i++) String2.log( String2.right(percent.format(timePeriodRequests[i] / nRequests), 9) + "% were for " + timePeriodOptions[i]); String2.log("Region Usage:"); for (int i = 0; i < regionOptions.length; i++) String2.log( String2.right(percent.format(regionRequests[i] / nRequests), 9) + "% were for " + regionOptions[i]); } String2.log( SSR.getTopN(printTopNMostRequested, " Most Requested .gif files", requestedFilesMap)); // data was successfully gathered from CWDataBrowserReset resetThread = null; cwDataBrowserReset = null; return true; }
/** Constructor */ public CWDataBrowser() throws Exception { super("gov.noaa.pfel.coastwatch.CWDataBrowser"); constructorDateTime = Calendar2.getCurrentISODateTimeStringLocal(); // addAttribute(new EmaLabel(this, "instructions")); addAttribute(dataSet = new EmaSelect(this, "dataSet")); addAttribute(region = new EmaSelect(this, "region")); addAttribute(timePeriod = new EmaSelect(this, "timePeriod")); addAttribute(date = new EmaSelect(this, "date")); addAttribute(formSubmitted = new EmaHidden(this, "formSubmitted")); addAttribute(submitForm = new EmaButton(this, "submitForm")); // one time things verbose = classRB2.getBoolean("verbose", false); // contextDirectory and logs (file will be in same dir as this class's source code, named // log.txt) contextDirectory = classRB2.getString("contextDirectory", ""); int logPo = fullClassName.lastIndexOf('.'); String logDir = String2.replaceAll(fullClassName.substring(0, logPo + 1), ".", "/"); String2.setupLog( false, false, String2.getClassPath() + logDir + "log.txt", // with / separator true, String2.logFileDefaultMaxSize); // append? String2.log( "\n" + String2.makeString('*', 80) + "\nCWDataBrowser.constructor " + constructorDateTime + "\nlogFile=" + String2.logFileName() + "\n" + String2.standardHelpAboutMessage()); // get baseDataDirectory (for access within this program) baseDataDirectory = classRB2.getString("dataDirectory", null); Test.ensureNotNull(baseDataDirectory, "dataDirectory"); // get dataServer (for web-based access to the data) dataServer = classRB2.getString("dataServer", null); Test.ensureNotNull(dataServer, "dataServer"); // how often should reset be called? resetEveryNMillis = classRB2.getInt("resetEveryNMinutes", 10) * 60000; // millis/min // printTopNMostRequested printTopNMostRequested = classRB2.getInt("printTopNMostRequested", 50); // lookForAllUnusedDataFiles lookForAllUnusedDataFiles = classRB2.getBoolean("lookForAllUnusedDataFiles", false); // get the name of the file with the small regions map regionsImage = classRB2.getString("regionsImage", ""); regionsImageTitle = classRB2.getString("regionsImage.title", ""); regionsImageAlt = classRB2.getString("regionsImage.alt", ""); // get title title = classRB2.getString("title.value", ""); // get dataSet properties dataSetOptions = classRB2.getString("dataSet.options", null).split("\f"); dataSetTitles = classRB2.getString("dataSet.title", null).split("\f"); dataSetDirectories = classRB2.getString("dataSet.directories", null).split("\f"); dataSetRegexs = classRB2.getString("dataSet.regexs", null).split("\f"); if (dataSetRequests == null) dataSetRequests = new int[dataSetOptions.length]; boolean trouble = dataSetOptions.length != (dataSetTitles.length - 1) || // 1 extra title (main) dataSetOptions.length != dataSetDirectories.length || dataSetOptions.length != dataSetRegexs.length; if (verbose || trouble) String2.log( "baseDataDirectory: " + baseDataDirectory + "\n" + "dataSetOptions: " + String2.toCSSVString(dataSetOptions) + "\n" + "dataSetTitles: " + String2.toNewlineString(dataSetTitles) + "\n" + "dataSetDirectories: " + String2.toCSSVString(dataSetDirectories) + "\n" + "dataSetRegexs: " + String2.toCSSVString(dataSetRegexs)); if (trouble) throw new RuntimeException( String2.ERROR + ": CWDataBrowser.reset " + "nDataSetOptions " + dataSetOptions.length + " != nDataSetTitles " + dataSetTitles.length + " != nDataSetDirectories " + dataSetDirectories.length + " != nDataSetRegexs " + dataSetRegexs.length); // get region properties regionOptions = classRB2.getString("region.options", null).split("\f"); regionTitles = classRB2.getString("region.title", null).split("\f"); regionRegexs = classRB2.getString("region.regexs", null).split("\f"); regionCoordinates = classRB2.getString("region.coordinates", null).split("\f"); regionRequests = new int[regionOptions.length]; trouble = regionOptions.length != (regionTitles.length - 1) || // 1 extra title (main) regionOptions.length != regionRegexs.length || regionOptions.length != regionCoordinates.length; if (verbose || trouble) String2.log( "regionOptions: " + String2.toCSSVString(regionOptions) + "\n" + "regionTitles: " + String2.toNewlineString(regionTitles) + "\n" + "regionRegexs: " + String2.toCSSVString(regionRegexs)); if (trouble) throw new RuntimeException( String2.ERROR + ": CWDataBrowser.reset " + "nRegionOptions " + regionOptions.length + " != nRegionTitles " + regionTitles.length + " != nRegionRegexs " + regionRegexs.length + " != nRegionCoordinates " + regionCoordinates.length); // get timePeriod properties timePeriodOptions = classRB2.getString("timePeriod.options", null).split("\f"); timePeriodTitles = classRB2.getString("timePeriod.title", null).split("\f"); timePeriodDirectories = classRB2.getString("timePeriod.directories", null).split("\f"); timePeriodRequests = new int[timePeriodOptions.length]; trouble = timePeriodOptions.length != (timePeriodTitles.length - 1) || // 1 extra title (main) timePeriodOptions.length != timePeriodDirectories.length; if (verbose || trouble) String2.log( "timePeriodOptions: " + String2.toCSSVString(timePeriodOptions) + "\n" + "timePeriodTitles: " + String2.toNewlineString(timePeriodTitles) + "\n" + "timePeriodDirectories: " + String2.toCSSVString(timePeriodDirectories)); if (trouble) throw new RuntimeException( String2.ERROR + ": CWDataBrowser.reset " + "nTimePeriodOptions " + timePeriodOptions.length + " != nTimePeriodTitles " + timePeriodTitles.length + " " + " != nTimePeriodDirectories " + timePeriodDirectories.length); // get 'get' properties // the first 'get' option must be .gif; a .gif file must be present before looking for others getOptions = classRB2.getString("get.options", null).split("\f"); getTitles = classRB2.getString("get.title", null).split("\f"); getDirectories = classRB2.getString("get.directories", null).split("\f"); getRegexs = classRB2.getString("get.regexs", null).split("\f"); getExtensions = classRB2.getString("get.extensions", null).split("\f"); hereIs = classRB2.getString("hereIs", null); hereIsAlt = classRB2.getString("hereIsAlt", null); trouble = getOptions.length != (getTitles.length - 1) || // 1 extra title (main) getOptions.length != getDirectories.length || getOptions.length != getRegexs.length || getOptions.length != getExtensions.length; if (verbose || trouble) String2.log( "getOptions: " + String2.toCSSVString(getOptions) + "\n" + "getDirectories: " + String2.toCSSVString(getDirectories) + "\n" + "getExtensions: " + String2.toCSSVString(getExtensions) + "\n" + "getRegexs: " + String2.toCSSVString(getRegexs)); if (trouble) throw new RuntimeException( String2.ERROR + ": CWDataBrowser.reset \n" + "nGetOptions " + getOptions.length + " != nGetTitles " + getTitles.length + " != nGetDirectories " + getDirectories.length + " != nGetRegexs " + getRegexs.length + " != nGetExtensions " + getExtensions.length); requestedFilesMap = new ConcurrentHashMap(128, 0.75f, 4); // thread-safe // EmaAttribute.verbose= true; // reset after attributes have been created runCWDataBrowserReset(); resetThread.join(); boolean ok = getDataFromReset(); // it should succeed first try if (!ok) throw new RuntimeException(String2.ERROR + " in CWDataBrowserReset."); }