diff --git a/intrace.appengine/.settings/com.google.appengine.eclipse.core.prefs b/intrace.appengine/.settings/com.google.appengine.eclipse.core.prefs index 3ea32a6..449f8e4 100644 --- a/intrace.appengine/.settings/com.google.appengine.eclipse.core.prefs +++ b/intrace.appengine/.settings/com.google.appengine.eclipse.core.prefs @@ -1,6 +1,5 @@ -#Mon Apr 23 22:28:35 BST 2012 eclipse.preferences.version=1 -filesCopiedToWebInfLib=appengine-api-1.0-sdk-1.6.4.jar|appengine-api-labs-1.6.4.jar|appengine-jsr107cache-1.6.4.jar|jsr107cache-1.1.jar|datanucleus-appengine-1.0.10.final.jar|datanucleus-core-1.1.5.jar|datanucleus-jpa-1.1.5.jar|geronimo-jpa_3.0_spec-1.1.1.jar|geronimo-jta_1.1_spec-1.1.1.jar|jdo2-api-2.3-eb.jar +filesCopiedToWebInfLib=appengine-api-labs.jar|appengine-jsr107cache-1.6.4.jar|jsr107cache-1.1.jar|appengine-api-1.0-sdk-1.6.4.jar|datanucleus-appengine-1.0.10.final.jar|datanucleus-core-1.1.5.jar|datanucleus-jpa-1.1.5.jar|geronimo-jpa_3.0_spec-1.1.1.jar|geronimo-jta_1.1_spec-1.1.1.jar|jdo2-api-2.3-eb.jar gaeDeployDialogSettings= gaeIsEclipseDefaultInstPath=true googleCloudSqlEnabled=false diff --git a/intrace.appengine/src/org/gaecounter/data/Counter.java b/intrace.appengine/src/org/gaecounter/data/Counter.java index 6137c78..ca44bbf 100644 --- a/intrace.appengine/src/org/gaecounter/data/Counter.java +++ b/intrace.appengine/src/org/gaecounter/data/Counter.java @@ -7,6 +7,8 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.jdo.PersistenceManager; import javax.jdo.Query; @@ -136,7 +138,10 @@ public class Counter return detachedList; } - public static Map> getPerFilePerDateMap(List xiList) + private static final Pattern sVerPattern = Pattern.compile("(.+)_([0-9]+(\\.[0-9]+)*)(\\..+)"); + + public static Map> getPerFilePerDateMap(List xiList, + boolean xiCollapseVers) { Map> lFileMap = new HashMap>(); @@ -146,6 +151,15 @@ public class Counter String lDateStr = lCounter.mDate; Integer lCount = lCounter.mCount; + if (xiCollapseVers) + { + Matcher matcher = sVerPattern.matcher(lFile); + if (matcher.matches()) + { + lFile = matcher.group(1) + "*" + matcher.group(4); + } + } + Map lDateMap = lFileMap.get(lFile); if (lDateMap == null) { @@ -153,7 +167,20 @@ public class Counter lFileMap.put(lFile, lDateMap); } - lDateMap.put(lDateStr, lCount); + if (xiCollapseVers) + { + Integer lAllVersCount = lDateMap.get(lDateStr); + if (lAllVersCount == null) + { + lAllVersCount = 0; + } + lAllVersCount += lCount; + lDateMap.put(lDateStr, lAllVersCount); + } + else + { + lDateMap.put(lDateStr, lCount); + } } return lFileMap; diff --git a/intrace.appengine/testsrc/org/gaecounter/CounterTest.java b/intrace.appengine/testsrc/org/gaecounter/CounterTest.java index 7da497b..7e8e0f7 100644 --- a/intrace.appengine/testsrc/org/gaecounter/CounterTest.java +++ b/intrace.appengine/testsrc/org/gaecounter/CounterTest.java @@ -18,25 +18,50 @@ public class CounterTest @Test public void testMapping() { - List lTestData = new ArrayList(); - lTestData.add(new Counter(Type.DAY, - Type.DAY.getPartialStr(2010, 1, 1), - "test.wav")); - lTestData.add(new Counter(Type.DAY, - Type.DAY.getPartialStr(2011, 2, 2), - "test.wav")); - lTestData.add(new Counter(Type.DAY, - Type.DAY.getPartialStr(2011, 2, 2), - "foo.wav")); + { + List lTestData = new ArrayList(); + lTestData.add(new Counter(Type.DAY, + Type.DAY.getPartialStr(2010, 1, 1), + "test.wav")); + lTestData.add(new Counter(Type.DAY, + Type.DAY.getPartialStr(2011, 2, 2), + "test.wav")); + lTestData.add(new Counter(Type.DAY, + Type.DAY.getPartialStr(2011, 2, 2), + "foo.wav")); - Map> map = Counter.getPerFilePerDateMap(lTestData); - assertEquals(2, map.keySet().size()); - assertTrue(map.keySet().toString(), map.keySet().contains("test.wav")); - assertTrue(map.keySet().toString(), map.keySet().contains("foo.wav")); - Map lData = map.get("test.wav"); - assertEquals(2, lData.keySet().size()); - assertTrue(lData.keySet().toString(), lData.keySet().contains("2010/01/01")); - assertTrue(lData.keySet().toString(), lData.keySet().contains("2011/02/02")); + Map> map = Counter.getPerFilePerDateMap(lTestData, false); + assertEquals(2, map.keySet().size()); + assertTrue(map.keySet().toString(), map.keySet().contains("test.wav")); + assertTrue(map.keySet().toString(), map.keySet().contains("foo.wav")); + Map lData = map.get("test.wav"); + assertEquals(2, lData.keySet().size()); + assertTrue(lData.keySet().toString(), lData.keySet().contains("2010/01/01")); + assertTrue(lData.keySet().toString(), lData.keySet().contains("2011/02/02")); + } + + { + List lTestData = new ArrayList(); + lTestData.add(new Counter(Type.DAY, + Type.DAY.getPartialStr(2010, 1, 1), + "test_1.0.1.wav")); + lTestData.add(new Counter(Type.DAY, + Type.DAY.getPartialStr(2010, 1, 1), + "test_1.0.2.wav")); + lTestData.add(new Counter(Type.DAY, + Type.DAY.getPartialStr(2011, 2, 2), + "test_1.0.3.wav")); + + Map> map = Counter.getPerFilePerDateMap(lTestData, true); + assertEquals(1, map.keySet().size()); + assertTrue(map.keySet().toString(), map.keySet().contains("test*.wav")); + Map lData = map.get("test*.wav"); + assertEquals(2, lData.keySet().size()); + assertTrue(lData.keySet().toString(), lData.keySet().contains("2010/01/01")); + assertEquals((Integer)2, lData.get("2010/01/01")); + assertTrue(lData.keySet().toString(), lData.keySet().contains("2011/02/02")); + assertEquals((Integer)1, lData.get("2011/02/02")); + } } @Test diff --git a/intrace.appengine/war/WEB-INF/lib/appengine-api-labs-1.6.4.jar b/intrace.appengine/war/WEB-INF/lib/appengine-api-labs.jar similarity index 100% rename from intrace.appengine/war/WEB-INF/lib/appengine-api-labs-1.6.4.jar rename to intrace.appengine/war/WEB-INF/lib/appengine-api-labs.jar diff --git a/intrace.appengine/war/downloads.jsp b/intrace.appengine/war/downloads.jsp index 1a6e4a6..5d419f2 100644 --- a/intrace.appengine/war/downloads.jsp +++ b/intrace.appengine/war/downloads.jsp @@ -38,7 +38,10 @@ Type lType = Type.WEEK; // Check file - String lFileStr = request.getParameter("file"); + String lFileStr = request.getParameter("file"); + + // Check whether to collapse versions + String lCollapseVersions = request.getParameter("collapseversions"); // Check type String lModeStr = request.getParameter("mode"); @@ -64,12 +67,13 @@ List lRecords = Counter.getAllByType(lFetchType); // Filename -> DateStr -> Count - Map> lPerFilePerDateStrDownloads = Counter.getPerFilePerDateMap(lRecords); + Map> lPerFilePerDateStrDownloads = Counter.getPerFilePerDateMap(lRecords, + (lCollapseVersions != null)); if (lType == Type.WEEK) { lPerFilePerDateStrDownloads = Counter.getFilePerWeekMap(lPerFilePerDateStrDownloads); } - + // Filenames List lFilenames = new ArrayList(lPerFilePerDateStrDownloads.keySet()); Collections.sort(lFilenames); @@ -80,7 +84,10 @@ lFileStr = Utils.dec(lFileStr); Map lSingleValue = lPerFilePerDateStrDownloads.get(lFileStr); lPerFilePerDateStrDownloads.clear(); - lPerFilePerDateStrDownloads.put(lFileStr, lSingleValue); + if (lSingleValue != null) + { + lPerFilePerDateStrDownloads.put(lFileStr, lSingleValue); + } } // Date strings @@ -183,16 +190,8 @@ } function setMode(mode) - { - if (getUrlVars()['file']) - { - window.location.href = "downloads.jsp?file=" + getUrlVars()['file'] + - "&mode=" + mode; - } - else - { - window.location.href = "downloads.jsp?mode=" + mode; - } + { + loadWithUrlArg('mode', mode); } function selectFile() @@ -201,16 +200,25 @@ var file = picker.value; if (file) { - if (getUrlVars()['mode']) + loadWithUrlArg('file', file); + } + } + + function loadWithUrlArg(key, value) + { + var args = getUrlVars(); + args[key] = value; + + var newUrl = "downloads.jsp?"; + for each (var item in ['mode','file','collapseversions']) + { + if (args[item]) { - window.location.href = "downloads.jsp?file=" + file + - "&mode=" + getUrlVars()['mode']; + newUrl += item + "=" + args[item] + "&"; } - else - { - window.location.href = "downloads.jsp?file=" + file; - } - } + } + + window.location.href = newUrl; } // Read a page's GET URL variables and return them as an associative array. @@ -226,6 +234,19 @@ } return vars; } + + function setCollapse() + { + var collapseEl = document.getElementById("collapseversions"); + if (collapseEl.checked) + { + loadWithUrlArg('collapseversions', true); + } + else + { + loadWithUrlArg('collapseversions'); + } + } -
+ + checked="checked" <% } %>/> Collapse Versions +
diff --git a/intrace.appengine/war/files/JTDA.app.tar b/intrace.appengine/war/files/JTDA.app.tar index 6770135..dcddeb8 100644 Binary files a/intrace.appengine/war/files/JTDA.app.tar and b/intrace.appengine/war/files/JTDA.app.tar differ diff --git a/intrace.appengine/war/files/jtda.jar b/intrace.appengine/war/files/jtda.jar index 7227ac5..179fb4c 100644 Binary files a/intrace.appengine/war/files/jtda.jar and b/intrace.appengine/war/files/jtda.jar differ diff --git a/intrace.appengine/war/stats.html b/intrace.appengine/war/stats.html deleted file mode 100644 index 2c2696c..0000000 --- a/intrace.appengine/war/stats.html +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - Google Visualization API Sample - - - - - - -
- - \ No newline at end of file