Compare commits

..

No commits in common. "master" and "Release_3" have entirely different histories.

258 changed files with 4759 additions and 14764 deletions

6
.gitignore vendored
View File

@ -6,8 +6,4 @@
*/genbin/*
asm3.2_*
asm_patch*
libsrc*
*private*
*genfile*
classes/
appengine-generated/
libsrc*

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
<!-- for some information on what you could do (e.g. targets to override). -->
<!-- If you delete this file and reopen the project it will be recreated. -->
<project name="org.intrace.visualvm" default="netbeans" basedir=".">
<description>Builds, tests, and runs the project org.intrace.visualvm.</description>
<import file="nbproject/build-impl.xml"/>
</project>

View File

@ -1,7 +0,0 @@
Manifest-Version: 1.0
OpenIDE-Module: org.intrace.visualvm
OpenIDE-Module-Install: org/intrace/visualvm/Installer.class
OpenIDE-Module-Layer: org/intrace/visualvm/layer.xml
OpenIDE-Module-Localizing-Bundle: org/intrace/visualvm/Bundle.properties
OpenIDE-Module-Specification-Version: 1.0
OpenIDE-Module-Name: InTrace: VisualVM Plugin

View File

@ -1,42 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
*** GENERATED FROM project.xml - DO NOT EDIT ***
*** EDIT ../build.xml INSTEAD ***
-->
<project name="org.intrace.visualvm-impl" basedir="..">
<fail message="Please build using Ant 1.7.1 or higher.">
<condition>
<not>
<antversion atleast="1.7.1"/>
</not>
</condition>
</fail>
<property file="nbproject/private/platform-private.properties"/>
<property file="nbproject/platform.properties"/>
<macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
<attribute name="name"/>
<attribute name="value"/>
<sequential>
<property name="@{name}" value="${@{value}}"/>
</sequential>
</macrodef>
<macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
<attribute name="property"/>
<attribute name="value"/>
<sequential>
<property name="@{property}" value="@{value}"/>
</sequential>
</macrodef>
<property file="${user.properties.file}"/>
<nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
<nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
<nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
<fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
<condition>
<not>
<contains string="${cluster.path.evaluated}" substring="platform"/>
</not>
</condition>
</fail>
<import file="${harness.dir}/build.xml"/>
</project>

View File

@ -1,5 +0,0 @@
cluster.path=\
${nbplatform.active.dir}/platform:\
${nbplatform.active.dir}/profiler:\
${nbplatform.active.dir}/visualvm
nbplatform.active=VisualVM_1.2.2

View File

@ -1,3 +0,0 @@
cp.extra=${tools.jar}
javac.source=1.6
javac.compilerargs=-Xlint -Xlint:-serial

View File

@ -1,72 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://www.netbeans.org/ns/project/1">
<type>org.netbeans.modules.apisupport.project</type>
<configuration>
<data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
<code-name-base>org.intrace.visualvm</code-name-base>
<standalone/>
<module-dependencies>
<dependency>
<code-name-base>com.sun.tools.visualvm.application</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<release-version>0-1</release-version>
<specification-version>1.2</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>com.sun.tools.visualvm.attach</code-name-base>
<run-dependency>
<release-version>0-1</release-version>
<specification-version>1.1</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>com.sun.tools.visualvm.core</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<release-version>0-1</release-version>
<specification-version>1.3</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>com.sun.tools.visualvm.host</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<release-version>0-1</release-version>
<specification-version>1.0</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>com.sun.tools.visualvm.tools</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<release-version>0-1</release-version>
<specification-version>1.1</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.openide.modules</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.13.1</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.openide.util</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.31.1.1</specification-version>
</run-dependency>
</dependency>
</module-dependencies>
<public-packages/>
</data>
</configuration>
</project>

View File

@ -1 +0,0 @@
OpenIDE-Module-Name=InTrace: Visual VM Plugin

View File

@ -1,20 +0,0 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package org.intrace.visualvm;
import org.intrace.visualvm.view.InTraceViewProvider;
import org.openide.modules.ModuleInstall;
/**
* Manages a module's lifecycle. Remember that an installer is optional and
* often not needed at all.
*/
public class Installer extends ModuleInstall {
@Override
public void restored() {
InTraceViewProvider.initialize();
}
}

View File

@ -1,50 +0,0 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package org.intrace.visualvm;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import org.openide.modules.InstalledFileLocator;
/**
*
* @author mch50
*/
public class Locator {
public static final String agentPath;
public static final String clientPath;
static {
File locatedFile = InstalledFileLocator.getDefault().locate("modules/ext/intrace-agent.jar", null, false); // NOI18N
if (locatedFile != null) {
agentPath = locatedFile.getAbsolutePath();
} else {
agentPath = null;
}
String osName = System.getProperty("os.name", "unknown");
if (osName.contains("Windows")) {
locatedFile = InstalledFileLocator.getDefault().locate("modules/ext/intrace-client-gui-win.jar", null, false); // NOI18N
if (locatedFile != null) {
clientPath = locatedFile.getAbsolutePath();
} else {
clientPath = null;
}
}
else if (osName.contains("Linux")) {
locatedFile = InstalledFileLocator.getDefault().locate("modules/ext/intrace-client-gui-linux.jar", null, false); // NOI18N
if (locatedFile != null) {
clientPath = locatedFile.getAbsolutePath();
} else {
clientPath = null;
}
}
else {
clientPath = null;
}
}
}

View File

@ -1 +0,0 @@
InTraceApplicationAction.title=InTrace Application...

View File

@ -1,43 +0,0 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package org.intrace.visualvm.actions;
import com.sun.tools.visualvm.application.Application;
import com.sun.tools.visualvm.application.jvm.Jvm;
import com.sun.tools.visualvm.application.jvm.JvmFactory;
import com.sun.tools.visualvm.core.ui.DataSourceWindowManager;
import com.sun.tools.visualvm.core.ui.actions.SingleDataSourceAction;
import java.awt.event.ActionEvent;
import org.intrace.visualvm.impl.InTraceDataSource;
import org.openide.util.NbBundle;
/**
*
* @author mch50
*/
public class InTraceApplicationAction extends SingleDataSourceAction<Application> {
@Override
protected void actionPerformed(Application app, ActionEvent actionEvent) {
InTraceDataSource dataSource = new InTraceDataSource(app);
DataSourceWindowManager.sharedInstance().openDataSource(dataSource);
}
@Override
protected boolean isEnabled(Application app) {
Jvm jvm = JvmFactory.getJVMFor(app);
return app.isLocalApplication() && jvm.isAttachable() && jvm.isGetSystemPropertiesSupported();
}
public static synchronized InTraceApplicationAction newInstance() {
return new InTraceApplicationAction();
}
private InTraceApplicationAction() {
super(Application.class);
putValue(NAME, NbBundle.getMessage(InTraceApplicationAction.class, "InTraceApplicationAction.title")); // NOI18N
}
}

View File

@ -1,23 +0,0 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package org.intrace.visualvm.impl;
import com.sun.tools.visualvm.application.Application;
import com.sun.tools.visualvm.core.datasource.DataSource;
/**
*
* @author mch50
*/
public class InTraceDataSource extends DataSource {
public final Application app;
public InTraceDataSource(Application app) {
super(app);
this.app = app;
}
}

View File

@ -1,89 +0,0 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package org.intrace.visualvm.impl;
import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.visualvm.application.Application;
import com.sun.tools.visualvm.application.jvm.Jvm;
import com.sun.tools.visualvm.application.jvm.JvmFactory;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.intrace.visualvm.Locator;
import org.openide.util.Exceptions;
/**
*
* @author mch50
*/
public class InTraceLoader {
public static interface StatusHandler {
public void handleStatus(String statusLine);
}
public static void loadAgent(Application app, StatusHandler handler) {
Jvm jvm = JvmFactory.getJVMFor(app);
if (app.isLocalApplication() && jvm.isAttachable() && jvm.isGetSystemPropertiesSupported()) {
try {
VirtualMachine vm = VirtualMachine.attach(String.valueOf(app.getPid()));
handler.handleStatus("Attached to JVM (PID: " + app.getPid() + ")");
vm.loadAgent(Locator.agentPath, "");
handler.handleStatus("InTrace Agent loaded");
} catch (Exception ex) {
handler.handleStatus("Exception thrown:\n" + throwableToString(ex));
Exceptions.printStackTrace(ex);
}
}
}
public static void launchClient(final StatusHandler handler) {
Runnable launchClientThread = new Runnable() {
@Override
public void run() {
try {
List<String> command = new ArrayList<String>();
command.add("java");
command.add("-jar");
command.add(Locator.clientPath);
ProcessBuilder builder = new ProcessBuilder(command);
System.out.println("Directory : " + System.getenv("temp"));
builder.start();
handler.handleStatus("InTrace Client launched");
} catch (Exception ex) {
handler.handleStatus("Exception thrown:\n" + throwableToString(ex));
Exceptions.printStackTrace(ex);
}
}
};
new Thread(launchClientThread).start();
}
private static String throwableToString(Throwable throwable) {
StringBuilder throwToStr = new StringBuilder();
if (throwable == null) {
throwToStr.append("null");
} else {
StringWriter strWriter = new StringWriter();
PrintWriter writer = new PrintWriter(strWriter);
throwable.printStackTrace(writer);
throwToStr.append(strWriter.toString());
}
return throwToStr.toString();
}
}

View File

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
<filesystem>
<folder name="VisualVM">
<folder name="ExplorerPopupSelection">
<file name="ExplorerPopupSelection-Separator-2000_1.instance" url="ExplorerPopupSelection-Separator-2000_1.instance">
<attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
<attr name="position" intvalue="2350"/>
</file>
<file name="org-intrace-visualvm-actions-InTraceApplicationAction.instance">
<attr name="instanceCreate" methodvalue="org.intrace.visualvm.actions.InTraceApplicationAction.newInstance"/>
<attr name="position" intvalue="2400"/>
</file>
</folder>
</folder>
</filesystem>

View File

@ -1,144 +0,0 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package org.intrace.visualvm.view;
import com.sun.tools.visualvm.core.ui.DataSourceView;
import com.sun.tools.visualvm.core.ui.components.DataViewComponent;
import java.awt.BorderLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import org.intrace.visualvm.Locator;
import org.intrace.visualvm.impl.InTraceLoader;
import org.intrace.visualvm.impl.InTraceDataSource;
import org.openide.util.Utilities;
/**
*
* @author mch50
*/
public class InTraceView extends DataSourceView {
private final InTraceDataSource application;
private JTextArea textArea;
private DataViewComponent dvc;
//Reusing an image from the sources:
private static final String IMAGE_PATH = "com/sun/tools/visualvm/coredump/resources/coredump.png"; // NOI18N
public InTraceView(InTraceDataSource application) {
super(application, "InTrace", new ImageIcon(Utilities.loadImage(IMAGE_PATH, true)).getImage(), 60, false);
this.application = application;
}
@Override
protected DataViewComponent createComponent() {
//Data area for master view:
JPanel generalDataArea = new JPanel();
generalDataArea.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));
generalDataArea.setOpaque(false);
JButton loadAgentButton = new JButton("Load InTrace Agent");
loadAgentButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
InTraceLoader.loadAgent(application.app, new InTraceLoader.StatusHandler() {
@Override
public void handleStatus(String statusLine) {
appendText(statusLine);
}
});
}
});
JButton launchClient = new JButton("Launch InTrace Client");
launchClient.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
InTraceLoader.launchClient(new InTraceLoader.StatusHandler() {
@Override
public void handleStatus(String statusLine) {
appendText(statusLine);
}
});
}
});
JButton clearStatus = new JButton("Clear Status Text");
clearStatus.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
clearText();
}
});
generalDataArea.add(loadAgentButton);
generalDataArea.add(launchClient);
generalDataArea.add(clearStatus);
//Master view:
DataViewComponent.MasterView masterView = new DataViewComponent.MasterView
("Control", null, generalDataArea);
//Configuration of master view:
DataViewComponent.MasterViewConfiguration masterConfiguration =
new DataViewComponent.MasterViewConfiguration(false);
//Add the master view and configuration view to the component:
dvc = new DataViewComponent(masterView, masterConfiguration);
//Add detail view to the component:
JPanel statusArea = new JPanel();
statusArea.setOpaque(false);
statusArea.setLayout(new BorderLayout());
textArea = new JTextArea(5, 20);
JScrollPane scrollPane = new JScrollPane(textArea);
scrollPane.setVerticalScrollBarPolicy(
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
textArea.setEditable(false);
textArea.setLineWrap(true);
textArea.setMargin(new Insets(10,10,10,10));
statusArea.add(scrollPane, BorderLayout.CENTER);
dvc.addDetailsView(new DataViewComponent.DetailsView(
"Status", null, 10, statusArea, null), DataViewComponent.BOTTOM_LEFT);
appendText("Agent Path: " + Locator.agentPath);
appendText("Client Path: " + Locator.clientPath);
if (Locator.clientPath == null) {
appendText("Warning: The Client is only supported on Windows " +
"and Linux");
}
else {
appendText("Ready");
}
return dvc;
}
private void appendText(String str) {
if (textArea != null) {
textArea.append(str + "\n");
}
}
private void clearText() {
if (textArea != null) {
textArea.setText("");
}
}
}

View File

@ -1,39 +0,0 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package org.intrace.visualvm.view;
import com.sun.tools.visualvm.core.ui.DataSourceView;
import com.sun.tools.visualvm.core.ui.DataSourceViewProvider;
import com.sun.tools.visualvm.core.ui.DataSourceViewsManager;
import org.intrace.visualvm.impl.InTraceDataSource;
/**
*
* @author mch50
*/
public class InTraceViewProvider extends DataSourceViewProvider<InTraceDataSource> {
private static DataSourceViewProvider<InTraceDataSource> instance = new InTraceViewProvider();
@Override
public boolean supportsViewFor(InTraceDataSource application) {
//Always shown:
return true;
}
@Override
public synchronized DataSourceView createView(final InTraceDataSource application) {
return new InTraceView(application);
}
public static void initialize() {
DataSourceViewsManager.sharedInstance().addViewProvider(instance, InTraceDataSource.class);
}
static void unregister() {
DataSourceViewsManager.sharedInstance().removeViewProvider(instance);
}
}

View File

@ -1,17 +1,10 @@
Full details available on the "InTrace Site":http://mchr3k.github.com/org.intrace/
h1. Main Projects
* org.intrace - InTrace Agent and GUI
* intrace.ecl.plugin - InTrace Eclipse Plugin
* intrace.ecl.feature - InTrace Eclipse Feature
* intrace.ecl.site - InTrace Eclipse Update Site
* intrace.appengine - InTrace AppEngine Update Site Hosting
* binaries - jars from InTrace releases
h2. Work in progress
* InTrace-VisualVM - VisualVM integration
* org.intrace.agentbug - Project containing simple Agent used to illustrate bug report to Sun
* org.intrace - InTrace Agent and CUI/GUI
* org.intrace.agentloader - Command line agent loader for loading an agent into a running JVM process
h2. Scratch Projects
* binaries - images and jars used by wiki pages
* org.intrace.agentbug - Project containing simple Agent used to illustrate bug report to Sun
* org.intrace.test - Dumping ground for toy classes used in manual testing

BIN
binaries/images/callers.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="lib" path="lib/junit-4.10.jar"/>
<classpathentry kind="lib" path="war/WEB-INF/lib/joda-time-2.0.jar"/>
<classpathentry kind="src" path="testsrc"/>
<classpathentry kind="con" path="com.google.appengine.eclipse.core.GAE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="output" path="war/WEB-INF/classes"/>
</classpath>

View File

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>intrace.appengine</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.google.gdt.eclipse.core.webAppProjectValidator</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.google.appengine.eclipse.core.enhancerbuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.google.appengine.eclipse.core.projectValidator</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>com.google.appengine.eclipse.core.gaeNature</nature>
</natures>
</projectDescription>

View File

@ -1,7 +0,0 @@
eclipse.preferences.version=1
filesCopiedToWebInfLib=appengine-api-1.0-sdk-1.9.2.jar|appengine-api-labs.jar|appengine-endpoints-deps.jar|appengine-endpoints.jar|appengine-jsr107cache-1.9.2.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|jsr107cache-1.1.jar
gaeDeployDialogSettings=
gaeIsEclipseDefaultInstPath=true
gaeLaunchAppInBrowser=true
googleCloudSqlEnabled=false
localDevMySqlEnabled=true

View File

@ -1,4 +0,0 @@
#Fri May 20 09:24:41 BST 2011
eclipse.preferences.version=1
warSrcDir=war
warSrcDirIsOutput=true

View File

@ -1,11 +0,0 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.7

Binary file not shown.

View File

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<jdoconfig xmlns="http://java.sun.com/xml/ns/jdo/jdoconfig"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://java.sun.com/xml/ns/jdo/jdoconfig">
<persistence-manager-factory name="transactions-optional">
<property name="javax.jdo.PersistenceManagerFactoryClass"
value="org.datanucleus.store.appengine.jdo.DatastoreJDOPersistenceManagerFactory"/>
<property name="javax.jdo.option.ConnectionURL" value="appengine"/>
<property name="javax.jdo.option.NontransactionalRead" value="true"/>
<property name="javax.jdo.option.NontransactionalWrite" value="true"/>
<property name="javax.jdo.option.RetainValues" value="true"/>
<property name="datanucleus.appengine.autoCreateDatastoreTxns" value="true"/>
</persistence-manager-factory>
</jdoconfig>

View File

@ -1,24 +0,0 @@
# A default log4j configuration for log4j users.
#
# To use this configuration, deploy it into your application's WEB-INF/classes
# directory. You are also encouraged to edit it as you like.
# Configure the console as our one appender
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%c] - %m%n
# tighten logging on the DataNucleus Categories
log4j.category.DataNucleus.JDO=WARN, A1
log4j.category.DataNucleus.Persistence=WARN, A1
log4j.category.DataNucleus.Cache=WARN, A1
log4j.category.DataNucleus.MetaData=WARN, A1
log4j.category.DataNucleus.General=WARN, A1
log4j.category.DataNucleus.Utility=WARN, A1
log4j.category.DataNucleus.Transaction=WARN, A1
log4j.category.DataNucleus.Datastore=WARN, A1
log4j.category.DataNucleus.ClassLoading=WARN, A1
log4j.category.DataNucleus.Plugin=WARN, A1
log4j.category.DataNucleus.ValueGeneration=WARN, A1
log4j.category.DataNucleus.Enhancer=WARN, A1
log4j.category.DataNucleus.SchemaTool=WARN, A1

View File

@ -1,68 +0,0 @@
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))
{
for (int ii = 13; ii <= 25; ii++)
CountDownloadsFilter.countDownload("test_0.1.jar", 2012, 2, ii);
for (int ii = 28; ii <= 29; ii++)
CountDownloadsFilter.countDownload("test_0.1.jar", 2012, 2, ii);
for (int ii = 1; ii <= 2; ii++)
CountDownloadsFilter.countDownload("test_0.1.jar", 2012, 3, ii);
for (int ii = 5; ii <= 10; ii++)
CountDownloadsFilter.countDownload("test_0.1.jar", 2012, 3, ii);
for (int ii = 12; ii <= 15; ii++)
CountDownloadsFilter.countDownload("test_0.1.jar", 2012, 3, ii);
}
xiResp.sendRedirect(lRedir);
}
}

View File

@ -1,149 +0,0 @@
package org.gaecounter;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicInteger;
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 javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
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
{
final AtomicInteger error = new AtomicInteger(-1);
if (xiResp instanceof HttpServletResponse)
{
xiResp = new HttpServletResponseWrapper((HttpServletResponse)xiResp) {
@Override
public void sendError(int sc) throws IOException {
error.set(sc);
super.sendError(sc);
}
@Override
public void sendError(int sc, String msg) throws IOException {
error.set(sc);
super.sendError(sc, msg);
}
};
}
xiChain.doFilter(xiReq, xiResp);
if (error.get() == -1 && 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");
}
}
}
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
}
}

View File

@ -1,34 +0,0 @@
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;
}
}
}

View File

@ -1,307 +0,0 @@
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.Map.Entry;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
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.DateMidnight;
import org.joda.time.DateTimeConstants;
import org.joda.time.DateTimeFieldType;
import org.joda.time.Days;
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});
}
},
WEEK("yyyy/MM/dd", Period.days(7))
{
@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});
}
},
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<Counter> getAllByType(Type xiType)
{
List<Counter> 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<Counter>)lQuery.execute(xiType);
detachedList = new ArrayList<Counter>();
for (Counter obj : list)
{
detachedList.add(pm.detachCopy(obj));
}
}
finally
{
pm.close();
}
return detachedList;
}
private static final Pattern sVerPattern = Pattern.compile("(.+)_([0-9]+(\\.[0-9]+)*)(\\..+)");
public static Map<String,Map<String,Integer>> getPerFilePerDateMap(List<Counter> xiList,
boolean xiCollapseVers)
{
Map<String,Map<String,Integer>> lFileMap = new HashMap<String, Map<String,Integer>>();
for (Counter lCounter : xiList)
{
String lFile = lCounter.mFile;
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<String, Integer> lDateMap = lFileMap.get(lFile);
if (lDateMap == null)
{
lDateMap = new HashMap<String, Integer>();
lFileMap.put(lFile, lDateMap);
}
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;
}
public static List<String> getDateStrs(Type xiType,
Partial xiStart,
Set<String> xiDataDateStrs)
{
List<String> lDateStrs = new ArrayList<String>();
if (xiDataDateStrs.size() > 0)
{
if (xiType == Type.WEEK)
{
DateMidnight foundMonday = new DateMidnight(xiStart.get(DateTimeFieldType.year()),
xiStart.get(DateTimeFieldType.monthOfYear()),
xiStart.get(DateTimeFieldType.dayOfMonth()));
while (foundMonday.getDayOfWeek() != DateTimeConstants.MONDAY)
{
foundMonday = foundMonday.plus(Days.ONE);
}
xiStart = new Partial(new DateTimeFieldType[]
{DateTimeFieldType.year(),
DateTimeFieldType.monthOfYear(),
DateTimeFieldType.dayOfMonth()},
new int[] {foundMonday.getYear(),
foundMonday.getMonthOfYear(),
foundMonday.getDayOfMonth()});
}
List<String> lInDataStrsList = new ArrayList<String>(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;
}
public static Map<String,Map<String,Integer>> getFilePerWeekMap(Map<String,Map<String,Integer>> xiPerFilePerDayData)
{
// Filename -> DateStr -> Count
Map<String,Map<String,Integer>> lRet = new HashMap<String, Map<String,Integer>>();
for (Entry<String,Map<String,Integer>> fileEntry : xiPerFilePerDayData.entrySet())
{
String file = fileEntry.getKey();
Map<String,Integer> perWeekData = new HashMap<String, Integer>();
lRet.put(file, perWeekData);
// DateStr -> Count
Map<String, Integer> perDateData = fileEntry.getValue();
List<String> dateStrs = new ArrayList<String>(perDateData.keySet());
Collections.sort(dateStrs);
DateMidnight nextPeriod = null;
int weekCount = 0;
boolean unrecordedItem = false;
// Iterate through the dates from oldest to newest
for (String datestr : dateStrs)
{
DateMidnight date = new DateMidnight(datestr.replace("/", "-"));
if (nextPeriod != null)
{
// We know when the next period starts so check whether this date
// is after the start of the next period
if (date.isEqual(nextPeriod) || date.isAfter(nextPeriod))
{
DateMidnight prevPeriod = nextPeriod.minusDays(7);
perWeekData.put(Type.DAY.getPartialStr(prevPeriod.getYear(),
prevPeriod.getMonthOfYear(),
prevPeriod.getDayOfMonth()),
weekCount);
weekCount = 0;
unrecordedItem = false;
}
}
// Add the count to the current period
Integer count = perDateData.get(datestr);
weekCount += count;
if (!unrecordedItem)
{
// If this is the first item in the new period - work out when the period ends
nextPeriod = date.plusDays(1);
while (nextPeriod.getDayOfWeek() != DateTimeConstants.MONDAY)
{
nextPeriod = nextPeriod.plusDays(1);
}
}
unrecordedItem = true;
}
if (unrecordedItem)
{
// Store the details of the final period
DateMidnight prevPeriod = nextPeriod.minusDays(7);
perWeekData.put(Type.DAY.getPartialStr(prevPeriod.getYear(),
prevPeriod.getMonthOfYear(),
prevPeriod.getDayOfMonth()),
weekCount);
}
}
return lRet;
}
}

View File

@ -1,17 +0,0 @@
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;
}
}

View File

@ -1,134 +0,0 @@
package org.gaecounter;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.HashMap;
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<Counter> lTestData = new ArrayList<Counter>();
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<String, Map<String, Integer>> 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<String, Integer> 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<Counter> lTestData = new ArrayList<Counter>();
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<String, Map<String, Integer>> map = Counter.getPerFilePerDateMap(lTestData, true);
assertEquals(1, map.keySet().size());
assertTrue(map.keySet().toString(), map.keySet().contains("test*.wav"));
Map<String, Integer> 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
public void testDateStrs()
{
Type t = Type.DAY;
Set<String> lDateStrs = new HashSet<String>();
lDateStrs.add(t.getPartialStr(2010, 12, 18));
lDateStrs.add(t.getPartialStr(2010, 12, 16));
List<String> 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));
}
@Test
public void testWeekConversion()
{
{
// Prepare data
Map<String,Map<String,Integer>> lData = new HashMap<String, Map<String,Integer>>();
Map<String,Integer> lDayData = new HashMap<String, Integer>();
lData.put("testfile", lDayData);
lDayData.put("2011/12/09", 1);
lDayData.put("2011/12/10", 1);
lDayData.put("2011/12/11", 1);
lDayData.put("2011/12/12", 1); // Monday
lDayData.put("2011/12/13", 1);
lDayData.put("2011/12/14", 1);
lDayData.put("2011/12/15", 1);
lDayData.put("2011/12/16", 1);
lDayData.put("2011/12/17", 1);
lDayData.put("2011/12/18", 1);
lDayData.put("2011/12/19", 1); // Monday
lDayData.put("2011/12/20", 1);
// Test method
Map<String, Map<String, Integer>> lResult = Counter.getFilePerWeekMap(lData);
Map<String, Integer> lWeekData = lResult.get("testfile");
assertEquals(3,lWeekData.size());
assertEquals(3,(int)lWeekData.get("2011/12/05"));
assertEquals(7,(int)lWeekData.get("2011/12/12"));
assertEquals(2,(int)lWeekData.get("2011/12/19"));
}
{
// Prepare data
Map<String,Map<String,Integer>> lData = new HashMap<String, Map<String,Integer>>();
Map<String,Integer> lDayData = new HashMap<String, Integer>();
lData.put("testfile", lDayData);
lDayData.put("2011/12/09", 1);
lDayData.put("2011/12/10", 1);
//lDayData.put("2011/12/12", 1); // Monday
//lDayData.put("2011/12/19", 1); // Monday
lDayData.put("2011/12/20", 1);
// Test method
Map<String, Map<String, Integer>> lResult = Counter.getFilePerWeekMap(lData);
Map<String, Integer> lWeekData = lResult.get("testfile");
assertEquals(2,lWeekData.size());
assertEquals(2,(int)lWeekData.get("2011/12/05"));
assertEquals(1,(int)lWeekData.get("2011/12/19"));
}
}
}

View File

@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>intracesite</application>
<version>1</version>
<!-- Configure java.util.logging -->
<system-properties>
<property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
</system-properties>
<static-files>
<include path="/**.html" />
<include path="/**.xml" />
<include path="/features/**" />
<exclude path="/plugins/**" />
<exclude path="/files/**" />
</static-files>
<admin-console>
<page name="Downloads" url="/downloads.jsp" />
</admin-console>
<threadsafe>true</threadsafe>
</appengine-web-app>

View File

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<jdoconfig xmlns="http://java.sun.com/xml/ns/jdo/jdoconfig"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://java.sun.com/xml/ns/jdo/jdoconfig">
<persistence-manager-factory name="transactions-optional">
<property name="javax.jdo.PersistenceManagerFactoryClass"
value="org.datanucleus.store.appengine.jdo.DatastoreJDOPersistenceManagerFactory"/>
<property name="javax.jdo.option.ConnectionURL" value="appengine"/>
<property name="javax.jdo.option.NontransactionalRead" value="true"/>
<property name="javax.jdo.option.NontransactionalWrite" value="true"/>
<property name="javax.jdo.option.RetainValues" value="true"/>
<property name="datanucleus.appengine.autoCreateDatastoreTxns" value="true"/>
</persistence-manager-factory>
</jdoconfig>

View File

@ -1,24 +0,0 @@
# A default log4j configuration for log4j users.
#
# To use this configuration, deploy it into your application's WEB-INF/classes
# directory. You are also encouraged to edit it as you like.
# Configure the console as our one appender
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%c] - %m%n
# tighten logging on the DataNucleus Categories
log4j.category.DataNucleus.JDO=WARN, A1
log4j.category.DataNucleus.Persistence=WARN, A1
log4j.category.DataNucleus.Cache=WARN, A1
log4j.category.DataNucleus.MetaData=WARN, A1
log4j.category.DataNucleus.General=WARN, A1
log4j.category.DataNucleus.Utility=WARN, A1
log4j.category.DataNucleus.Transaction=WARN, A1
log4j.category.DataNucleus.Datastore=WARN, A1
log4j.category.DataNucleus.ClassLoading=WARN, A1
log4j.category.DataNucleus.Plugin=WARN, A1
log4j.category.DataNucleus.ValueGeneration=WARN, A1
log4j.category.DataNucleus.Enhancer=WARN, A1
log4j.category.DataNucleus.SchemaTool=WARN, A1

Some files were not shown because too many files have changed in this diff Show More