diff --git a/.gitignore b/.gitignore
index 79af0f6..249c1ca 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,4 +8,6 @@ asm3.2_*
asm_patch*
libsrc*
*private*
-*genfile*
\ No newline at end of file
+*genfile*
+classes/
+appengine-generated/
\ No newline at end of file
diff --git a/intrace.appengine/.classpath b/intrace.appengine/.classpath
index 9a9cdee..37202b8 100644
--- a/intrace.appengine/.classpath
+++ b/intrace.appengine/.classpath
@@ -3,5 +3,8 @@
+
+
+
diff --git a/intrace.appengine/.settings/com.google.appengine.eclipse.core.prefs b/intrace.appengine/.settings/com.google.appengine.eclipse.core.prefs
index 1427f4f..04c4075 100644
--- a/intrace.appengine/.settings/com.google.appengine.eclipse.core.prefs
+++ b/intrace.appengine/.settings/com.google.appengine.eclipse.core.prefs
@@ -1,3 +1,4 @@
-#Mon Nov 07 21:54:15 GMT 2011
+#Sun Nov 13 21:28:21 GMT 2011
eclipse.preferences.version=1
-filesCopiedToWebInfLib=
+filesCopiedToWebInfLib=appengine-api-1.0-sdk-1.5.5.jar|appengine-api-labs-1.5.5.jar|appengine-jsr107cache-1.5.5.jar|jsr107cache-1.1.jar|datanucleus-appengine-1.0.9.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=
diff --git a/intrace.appengine/lib/junit-4.10.jar b/intrace.appengine/lib/junit-4.10.jar
new file mode 100644
index 0000000..bf5c0b9
Binary files /dev/null and b/intrace.appengine/lib/junit-4.10.jar differ
diff --git a/intrace.appengine/src/org/gaecounter/ActionServlet.java b/intrace.appengine/src/org/gaecounter/ActionServlet.java
new file mode 100644
index 0000000..8ef68d1
--- /dev/null
+++ b/intrace.appengine/src/org/gaecounter/ActionServlet.java
@@ -0,0 +1,76 @@
+package org.gaecounter;
+
+import java.io.IOException;
+
+import javax.jdo.PersistenceManager;
+import javax.jdo.Query;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.gaecounter.data.Counter;
+import org.gaecounter.data.PMF;
+
+public class ActionServlet extends HttpServlet
+{
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ protected void doGet(HttpServletRequest xiReq,
+ HttpServletResponse xiResp)
+ throws ServletException,
+ IOException
+ {
+ String lAction = xiReq.getParameter("action");
+ String lRedir = xiReq.getParameter("redir");
+
+ if ("clear".equals(lAction) ||
+ "clearfile".equals(lAction))
+ {
+ PersistenceManager pm = PMF.get().getPersistenceManager();
+ try
+ {
+ Query lDeletion = pm.newQuery(Counter.class);
+ if ("clearfile".equals(lAction))
+ {
+ String lFile = Utils.dec(xiReq.getParameter("file"));
+ lDeletion.setFilter("mFile == mFilenameParam");
+ lDeletion.declareParameters("String mFilenameParam");
+ lDeletion.deletePersistentAll(lFile);
+ }
+ else
+ {
+ lDeletion.deletePersistentAll();
+ }
+ }
+ finally
+ {
+ pm.close();
+ }
+ }
+ else if ("testdata".equals(lAction))
+ {
+ CountDownloadsFilter.countDownload("test_0.1.jar", 2010, 1, 1);
+ CountDownloadsFilter.countDownload("test_0.1.jar", 2010, 1, 1);
+ CountDownloadsFilter.countDownload("test_0.1.jar", 2010, 1, 2);
+ CountDownloadsFilter.countDownload("test_0.1.jar", 2010, 2, 2);
+ CountDownloadsFilter.countDownload("test_0.1.jar", 2010, 3, 2);
+ CountDownloadsFilter.countDownload("test_0.2.jar", 2010, 4, 2);
+ CountDownloadsFilter.countDownload("test_0.2.jar", 2010, 5, 2);
+ CountDownloadsFilter.countDownload("test_0.2.jar", 2010, 5, 2);
+ CountDownloadsFilter.countDownload("test_0.2.jar", 2010, 6, 2);
+ CountDownloadsFilter.countDownload("test_0.3.jar", 2011, 1, 1);
+ CountDownloadsFilter.countDownload("test_0.3.jar", 2011, 1, 1);
+ CountDownloadsFilter.countDownload("test_0.3.jar", 2011, 1, 2);
+ CountDownloadsFilter.countDownload("test_0.3.jar", 2011, 2, 2);
+ CountDownloadsFilter.countDownload("test_0.3.jar", 2011, 3, 2);
+ CountDownloadsFilter.countDownload("test_0.4.jar", 2011, 4, 2);
+ CountDownloadsFilter.countDownload("test_0.4.jar", 2011, 5, 2);
+ CountDownloadsFilter.countDownload("test_0.4.jar", 2011, 5, 2);
+ CountDownloadsFilter.countDownload("test_0.4.jar", 2011, 6, 2);
+ }
+
+ xiResp.sendRedirect(lRedir);
+ }
+}
diff --git a/intrace.appengine/src/org/gaecounter/CountDownloadsFilter.java b/intrace.appengine/src/org/gaecounter/CountDownloadsFilter.java
new file mode 100644
index 0000000..d4de20a
--- /dev/null
+++ b/intrace.appengine/src/org/gaecounter/CountDownloadsFilter.java
@@ -0,0 +1,128 @@
+package org.gaecounter;
+
+import java.io.IOException;
+
+import javax.jdo.JDOCanRetryException;
+import javax.jdo.JDOObjectNotFoundException;
+import javax.jdo.PersistenceManager;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+
+import org.gaecounter.data.Counter;
+import org.gaecounter.data.Counter.Type;
+import org.gaecounter.data.PMF;
+import org.joda.time.DateTime;
+
+public class CountDownloadsFilter implements Filter
+{
+ @Override
+ public void init(FilterConfig xiConfig) throws ServletException
+ {
+ // Do nothing
+ }
+
+ @Override
+ public void doFilter(ServletRequest xiReq,
+ ServletResponse xiResp,
+ FilterChain xiChain)
+ throws IOException,
+ ServletException
+ {
+ if (xiReq instanceof HttpServletRequest)
+ {
+ HttpServletRequest lHttpReq = (HttpServletRequest)xiReq;
+ String lReqURI = lHttpReq.getRequestURI();
+ DateTime lNow = new DateTime();
+ countDownload(lReqURI, lNow.getYear(), lNow.getMonthOfYear(), lNow.getDayOfMonth());
+ if (lReqURI.endsWith(".so"))
+ {
+ xiResp.setContentType("application/octet-stream");
+ }
+ }
+ xiChain.doFilter(xiReq, xiResp);
+ }
+
+ public static void countDownload(String xiReqURI, int y, int m, int d)
+ {
+ String lYStr = Type.YEAR.getPartialStr(y, m, d);
+ String lYStrKey = Counter.getKey(xiReqURI, lYStr);
+ String lYMStr = Type.MONTH.getPartialStr(y, m, d);
+ String lYMStrKey = Counter.getKey(xiReqURI, lYMStr);
+ String lYMDStr = Type.DAY.getPartialStr(y, m, d);
+ String lYMDStrKey = Counter.getKey(xiReqURI, lYMDStr);
+
+ PersistenceManager pm = PMF.get().getPersistenceManager();
+ try
+ {
+ incrementCounter(pm, lYStrKey, Type.YEAR, lYStr, xiReqURI);
+ incrementCounter(pm, lYMStrKey, Type.MONTH, lYMStr, xiReqURI);
+ incrementCounter(pm, lYMDStrKey, Type.DAY, lYMDStr, xiReqURI);
+ }
+ finally
+ {
+ pm.close();
+ }
+ }
+
+ private static void incrementCounter(PersistenceManager xiPm,
+ String xiKey,
+ Type xiType,
+ String xiDateStr,
+ String xiReqURI)
+ {
+ try
+ {
+ int retries = 0;
+ int NUM_RETRIES = 10;
+ while (true) // break out below
+ {
+ retries++;
+
+ xiPm.currentTransaction().begin();
+
+ Counter lCounter = null;
+ try
+ {
+ lCounter = xiPm.getObjectById(Counter.class, xiKey);
+ lCounter.incrementCount();
+ }
+ catch (JDOObjectNotFoundException ex)
+ {
+ lCounter = new Counter(xiType, xiDateStr, xiReqURI);
+ }
+ xiPm.makePersistent(lCounter);
+
+ try
+ {
+ xiPm.currentTransaction().commit();
+ break;
+ }
+ catch (JDOCanRetryException ex)
+ {
+ if (retries == NUM_RETRIES)
+ {
+ throw ex;
+ }
+ }
+ }
+ }
+ finally
+ {
+ if (xiPm.currentTransaction().isActive())
+ {
+ xiPm.currentTransaction().commit();
+ }
+ }
+ }
+
+ @Override
+ public void destroy()
+ {
+ // Do nothing
+ }
+}
diff --git a/intrace.appengine/src/org/gaecounter/Utils.java b/intrace.appengine/src/org/gaecounter/Utils.java
new file mode 100644
index 0000000..28a73f0
--- /dev/null
+++ b/intrace.appengine/src/org/gaecounter/Utils.java
@@ -0,0 +1,34 @@
+package org.gaecounter;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+
+public class Utils
+{
+ public static String enc(String xiVal)
+ {
+ try
+ {
+ return URLEncoder.encode(xiVal, "UTF-8");
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ // We will never hit this
+ return null;
+ }
+ }
+
+ public static String dec(String xiVal)
+ {
+ try
+ {
+ return URLDecoder.decode(xiVal, "UTF-8");
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ // We will never hit this
+ return null;
+ }
+ }
+}
diff --git a/intrace.appengine/src/org/gaecounter/data/Counter.java b/intrace.appengine/src/org/gaecounter/data/Counter.java
new file mode 100644
index 0000000..515afc1
--- /dev/null
+++ b/intrace.appengine/src/org/gaecounter/data/Counter.java
@@ -0,0 +1,174 @@
+package org.gaecounter.data;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jdo.PersistenceManager;
+import javax.jdo.Query;
+import javax.jdo.annotations.PersistenceCapable;
+import javax.jdo.annotations.Persistent;
+import javax.jdo.annotations.PrimaryKey;
+
+import org.joda.time.DateTimeFieldType;
+import org.joda.time.Partial;
+import org.joda.time.Period;
+
+@PersistenceCapable
+public class Counter
+{
+ public Counter(Type mType, String mDate, String mFile)
+ {
+ this.mKey = getKey(mFile, mDate);
+ this.mType = mType;
+ this.mDate = mDate;
+ this.mFile = mFile;
+ this.mCount = 1;
+ }
+
+ public static String getKey(String xiFile, String xiDate)
+ {
+ return xiFile + "_" + xiDate;
+ }
+
+ @PrimaryKey
+ @Persistent
+ public String mKey;
+ public enum Type
+ {
+ YEAR("yyyy", Period.years(1))
+ {
+ @Override
+ public Partial getPartial(int y, int m, int d)
+ {
+ return new Partial(new DateTimeFieldType[]
+ {DateTimeFieldType.year()},
+ new int[] {y});
+ }
+ },
+ MONTH("yyyy/MM", Period.months(1))
+ {
+ @Override
+ public Partial getPartial(int y, int m, int d)
+ {
+ return new Partial(new DateTimeFieldType[]
+ {DateTimeFieldType.year(),
+ DateTimeFieldType.monthOfYear()},
+ new int[] {y, m});
+ }
+ },
+ DAY("yyyy/MM/dd", Period.days(1))
+ {
+ @Override
+ public Partial getPartial(int y, int m, int d)
+ {
+ return new Partial(new DateTimeFieldType[]
+ {DateTimeFieldType.year(),
+ DateTimeFieldType.monthOfYear(),
+ DateTimeFieldType.dayOfMonth()},
+ new int[] {y, m, d});
+ }
+ };
+ private final String mFormat;
+ public final Period mPeriod;
+ private Type (String xiF, Period xiP) {mFormat = xiF; mPeriod = xiP;}
+ public Partial getPartial(int y, int m, int d) {return null;}
+ public String getPartialStr(int y, int m, int d)
+ {
+ return getPartial(y, m, d).toString(mFormat);
+ }
+ }
+ @Persistent
+ public Type mType;
+ @Persistent
+ public String mDate;
+ @Persistent
+ public String mFile;
+ @Persistent
+ public Integer mCount;
+
+ public void incrementCount()
+ {
+ mCount++;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static List getAllByType(Type xiType)
+ {
+ List detachedList = null, list = null;
+ PersistenceManager pm = PMF.get().getPersistenceManager();
+ try
+ {
+ Query lQuery = pm.newQuery(Counter.class);;
+ lQuery.setFilter("mType == mTypeParam");
+ lQuery.declareParameters("String mTypeParam");
+ list = (List)lQuery.execute(xiType);
+ detachedList = new ArrayList();
+ for (Counter obj : list)
+ {
+ detachedList.add(pm.detachCopy(obj));
+ }
+
+ }
+ finally
+ {
+ pm.close();
+ }
+ return detachedList;
+ }
+
+ public static Map> getPerFilePerDateMap(List xiList)
+ {
+ Map> lFileMap = new HashMap>();
+
+ for (Counter lCounter : xiList)
+ {
+ String lFile = lCounter.mFile;
+ String lDateStr = lCounter.mDate;
+ Integer lCount = lCounter.mCount;
+
+ Map lDateMap = lFileMap.get(lFile);
+ if (lDateMap == null)
+ {
+ lDateMap = new HashMap();
+ lFileMap.put(lFile, lDateMap);
+ }
+
+ lDateMap.put(lDateStr, lCount);
+ }
+
+ return lFileMap;
+ }
+
+ public static List getDateStrs(Type xiType,
+ Partial xiStart,
+ Set xiDataDateStrs)
+ {
+ List lDateStrs = new ArrayList();
+
+ if (xiDataDateStrs.size() > 0)
+ {
+ List lInDataStrsList = new ArrayList(xiDataDateStrs);
+ Collections.sort(lInDataStrsList);
+ String lOldestDate = lInDataStrsList.get(0);
+
+ Partial lDate = xiStart;
+ String lDateStr = lDate.toString(xiType.mFormat);
+
+ while (lDateStr.compareTo(lOldestDate) >= 0)
+ {
+ lDateStrs.add(lDateStr);
+ lDate = lDate.minus(xiType.mPeriod);
+ lDateStr = lDate.toString(xiType.mFormat);
+ }
+ lDateStrs.add(lDateStr);
+
+ Collections.reverse(lDateStrs);
+ }
+ return lDateStrs;
+ }
+
+}
diff --git a/intrace.appengine/src/org/gaecounter/data/PMF.java b/intrace.appengine/src/org/gaecounter/data/PMF.java
new file mode 100644
index 0000000..9793723
--- /dev/null
+++ b/intrace.appengine/src/org/gaecounter/data/PMF.java
@@ -0,0 +1,17 @@
+package org.gaecounter.data;
+
+import javax.jdo.JDOHelper;
+import javax.jdo.PersistenceManagerFactory;
+
+public final class PMF
+{
+ private static final PersistenceManagerFactory pmfInstance = JDOHelper
+ .getPersistenceManagerFactory("transactions-optional");
+
+ private PMF() { }
+
+ public static PersistenceManagerFactory get()
+ {
+ return pmfInstance;
+ }
+}
\ No newline at end of file
diff --git a/intrace.appengine/testsrc/org/gaecounter/CounterTest.java b/intrace.appengine/testsrc/org/gaecounter/CounterTest.java
new file mode 100644
index 0000000..ac777ef
--- /dev/null
+++ b/intrace.appengine/testsrc/org/gaecounter/CounterTest.java
@@ -0,0 +1,58 @@
+package org.gaecounter;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.gaecounter.data.Counter;
+import org.gaecounter.data.Counter.Type;
+import org.junit.Test;
+
+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"));
+
+ 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"));
+ }
+
+ @Test
+ public void testDateStrs()
+ {
+ Type t = Type.DAY;
+ Set lDateStrs = new HashSet();
+ lDateStrs.add(t.getPartialStr(2010, 12, 18));
+ lDateStrs.add(t.getPartialStr(2010, 12, 16));
+
+ List dateStrs = Counter.getDateStrs(Type.DAY, Type.DAY.getPartial(2010, 12, 20), lDateStrs);
+ assertEquals(6, dateStrs.size());
+ assertEquals("2010/12/15", dateStrs.get(0));
+ assertEquals("2010/12/16", dateStrs.get(1));
+ assertEquals("2010/12/17", dateStrs.get(2));
+ assertEquals("2010/12/18", dateStrs.get(3));
+ assertEquals("2010/12/19", dateStrs.get(4));
+ assertEquals("2010/12/20", dateStrs.get(5));
+ }
+}
diff --git a/intrace.appengine/war/WEB-INF/appengine-web.xml b/intrace.appengine/war/WEB-INF/appengine-web.xml
index 0dbde18..766ffc7 100644
--- a/intrace.appengine/war/WEB-INF/appengine-web.xml
+++ b/intrace.appengine/war/WEB-INF/appengine-web.xml
@@ -9,9 +9,14 @@
-
-
-
-
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/intrace.appengine/war/WEB-INF/lib/joda-time-2.0.jar b/intrace.appengine/war/WEB-INF/lib/joda-time-2.0.jar
new file mode 100644
index 0000000..169a7a4
Binary files /dev/null and b/intrace.appengine/war/WEB-INF/lib/joda-time-2.0.jar differ
diff --git a/intrace.appengine/war/WEB-INF/web.xml b/intrace.appengine/war/WEB-INF/web.xml
index 5755f49..27ef3d9 100644
--- a/intrace.appengine/war/WEB-INF/web.xml
+++ b/intrace.appengine/war/WEB-INF/web.xml
@@ -4,6 +4,28 @@ xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
+
+
+ CountDownloadsFilter
+ org.gaecounter.CountDownloadsFilter
+
+
+
+ CountDownloadsFilter
+ /plugins/*
+ /files/*
+
+
+
+ Action
+ org.gaecounter.ActionServlet
+
+
+
+ Action
+ /action
+
+
index.html
diff --git a/intrace.appengine/war/downloads.jsp b/intrace.appengine/war/downloads.jsp
new file mode 100644
index 0000000..be2ca54
--- /dev/null
+++ b/intrace.appengine/war/downloads.jsp
@@ -0,0 +1,161 @@
+<%@ page import="javax.jdo.PersistenceManager" %>
+<%@ page import="javax.jdo.Query" %>
+<%@ page import="org.gaecounter.data.Counter" %>
+<%@ page import="org.gaecounter.data.Counter.Type" %>
+<%@ page import="org.gaecounter.data.PMF" %>
+<%@ page import="org.gaecounter.Utils" %>
+<%@ page import="java.util.List" %>
+<%@ page import="java.util.ArrayList" %>
+<%@ page import="java.util.Iterator" %>
+<%@ page import="java.util.Map" %>
+<%@ page import="java.util.Map.Entry" %>
+<%@ page import="java.util.HashMap" %>
+<%@ page import="java.util.Collections" %>
+<%@ page import="java.util.Set" %>
+<%@ page import="java.util.HashSet" %>
+<%@ page import="org.joda.time.DateTime" %>
+
+
+
+ Downloads
+
+
+
+
+ <%
+ // Set type
+ Type lType = Type.DAY;
+
+ // Check type
+ String lModeStr = request.getParameter("mode");
+ if ("month".equals(lModeStr))
+ {
+ lType = Type.MONTH;
+ }
+ else if ("year".equals(lModeStr))
+ {
+ lType = Type.YEAR;
+ }
+
+ // Fetch data
+ List lRecords = Counter.getAllByType(lType);
+
+ // Filename -> DateStr -> Count
+ Map> lPerDateStrDownloads = Counter.getPerFilePerDateMap(lRecords);
+
+ // Date strings
+ Set dateStrsSet = new HashSet();
+ for (String file : lPerDateStrDownloads.keySet())
+ {
+ dateStrsSet.addAll(lPerDateStrDownloads.get(file).keySet());
+ }
+ DateTime lNow = new DateTime();
+ List dateStrs = Counter.getDateStrs(lType,
+ lType.getPartial(lNow.getYear(), lNow.getMonthOfYear(), lNow.getDayOfMonth()),
+ dateStrsSet);
+ %>
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/intrace.appengine/war/files/JTDA.app.tar b/intrace.appengine/war/files/JTDA.app.tar
new file mode 100644
index 0000000..b583785
Binary files /dev/null and b/intrace.appengine/war/files/JTDA.app.tar differ
diff --git a/intrace.appengine/war/files/emmacheck-0.2.jar b/intrace.appengine/war/files/emmacheck-0.2.jar
new file mode 100644
index 0000000..504e3c4
Binary files /dev/null and b/intrace.appengine/war/files/emmacheck-0.2.jar differ
diff --git a/intrace.appengine/war/files/inmemprofiler.dll b/intrace.appengine/war/files/inmemprofiler.dll
new file mode 100644
index 0000000..3e01f00
Binary files /dev/null and b/intrace.appengine/war/files/inmemprofiler.dll differ
diff --git a/intrace.appengine/war/files/inmemprofiler.jar b/intrace.appengine/war/files/inmemprofiler.jar
new file mode 100644
index 0000000..c13dd0d
Binary files /dev/null and b/intrace.appengine/war/files/inmemprofiler.jar differ
diff --git a/intrace.appengine/war/files/intrace-agent.jar b/intrace.appengine/war/files/intrace-agent.jar
new file mode 100644
index 0000000..cd3b3e5
Binary files /dev/null and b/intrace.appengine/war/files/intrace-agent.jar differ
diff --git a/intrace.appengine/war/files/intrace-ui.jar b/intrace.appengine/war/files/intrace-ui.jar
new file mode 100644
index 0000000..a0ab0d2
Binary files /dev/null and b/intrace.appengine/war/files/intrace-ui.jar differ
diff --git a/intrace.appengine/war/files/jtda.jar b/intrace.appengine/war/files/jtda.jar
new file mode 100644
index 0000000..f25b6ca
Binary files /dev/null and b/intrace.appengine/war/files/jtda.jar differ
diff --git a/intrace.appengine/war/files/libinmemprofiler.so b/intrace.appengine/war/files/libinmemprofiler.so
new file mode 100644
index 0000000..e9b17e1
Binary files /dev/null and b/intrace.appengine/war/files/libinmemprofiler.so differ
diff --git a/intrace.appengine/war/files/swtjar.jar b/intrace.appengine/war/files/swtjar.jar
new file mode 100644
index 0000000..67a330e
Binary files /dev/null and b/intrace.appengine/war/files/swtjar.jar differ
diff --git a/intrace.appengine/war/stats.html b/intrace.appengine/war/stats.html
new file mode 100644
index 0000000..2c2696c
--- /dev/null
+++ b/intrace.appengine/war/stats.html
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+ Google Visualization API Sample
+
+
+
+
+
+
+
+
+
\ No newline at end of file