Skip to content
This repository has been archived by the owner on Jul 1, 2021. It is now read-only.

Commit

Permalink
neo4j plugin works on little test. I have to see how to optimize tran…
Browse files Browse the repository at this point in the history
…saction with setter
  • Loading branch information
sim51 committed Nov 22, 2011
1 parent ac227bf commit e7682c9
Show file tree
Hide file tree
Showing 19 changed files with 157 additions and 108 deletions.
2 changes: 1 addition & 1 deletion .classpath
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry excluding="views/**" kind="src" path="app"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="app"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="/usr/local/play/play-1.2.3/framework/play-1.2.3.jar" sourcepath="/usr/local/play/play-1.2.3/framework/src"/>
<classpathentry kind="lib" path="/home/bsimard/workspace_logisima/EntreePlatDessert/plugins/neo4j/lib/scala-library-2.9.0-1.jar"/>
Expand Down
1 change: 0 additions & 1 deletion .project
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,4 @@
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.playframework.playclipse.playNature</nature>
</natures>

</projectDescription>
11 changes: 0 additions & 11 deletions app/play/module/neo4j/Import.java

This file was deleted.

14 changes: 14 additions & 0 deletions app/play/module/neo4j/Neo4jController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package play.module.neo4j;

import play.mvc.Controller;

public class Neo4jController extends Controller {

public static void importYml(String fileName) {

}

public static void deleteAll() {
}

}
1 change: 1 addition & 0 deletions build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

<path id="project.classpath">
<pathelement path="${play.path}/framework/classes"/>
<pathelement path="./app"/>
<fileset dir="${play.path}/framework/lib">
<include name="*.jar"/>
</fileset>
Expand Down
3 changes: 3 additions & 0 deletions eclipse/Connect JPDA to neo4j.launch
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="4"/>
</listAttribute>
<stringAttribute key="org.eclipse.debug.core.source_locator_id" value="org.eclipse.jdt.launching.sourceLocator.JavaSourceLookupDirector"/>
<stringAttribute key="org.eclipse.debug.core.source_locator_memento" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;sourceLookupDirector&gt;&#10;&lt;sourceContainers duplicates=&quot;false&quot;&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;EntreePlatDessert&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;default/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.debug.core.containerType.default&quot;/&gt;&#10;&lt;/sourceContainers&gt;&#10;&lt;/sourceLookupDirector&gt;&#10;"/>
<booleanAttribute key="org.eclipse.jdt.launching.ALLOW_TERMINATE" value="false"/>
<mapAttribute key="org.eclipse.jdt.launching.CONNECT_MAP">
<mapEntry key="hostname" value="localhost"/>
<mapEntry key="port" value="8000"/>
<mapEntry key="timeout" value="20000"/>
</mapAttribute>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="neo4j"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_CONNECTOR_ID" value="org.eclipse.jdt.launching.socketAttachConnector"/>
Expand Down
21 changes: 0 additions & 21 deletions eclipse/Test neo4j.launch

This file was deleted.

2 changes: 1 addition & 1 deletion eclipse/classes/play.plugins
Original file line number Diff line number Diff line change
@@ -1 +1 @@
399:play.modules.neo4j.Neo4jPlugin
1000:play.modules.neo4j.Neo4jPlugin
Binary file removed eclipse/classes/play/module/neo4j/Import.class
Binary file not shown.
Binary file modified eclipse/classes/play/modules/neo4j/Neo4jPlugin.class
Binary file not shown.
20 changes: 0 additions & 20 deletions eclipse/neo4j.launch

This file was deleted.

Binary file modified lib/play-neo4j.jar
Binary file not shown.
10 changes: 0 additions & 10 deletions src/models/relationship/EntityRelationType.java

This file was deleted.

2 changes: 1 addition & 1 deletion src/play.plugins
Original file line number Diff line number Diff line change
@@ -1 +1 @@
399:play.modules.neo4j.Neo4jPlugin
1000:play.modules.neo4j.Neo4jPlugin
21 changes: 20 additions & 1 deletion src/play/modules/neo4j/Neo4jPlugin.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package play.modules.neo4j;

import org.neo4j.graphdb.GraphDatabaseService;

import play.Logger;
import play.Play;
import play.Play.Mode;
Expand All @@ -23,6 +25,7 @@ public void onApplicationStart() {
Logger.info("Starting neo4j database");
if (Neo4j.db() == null) {
Neo4j.initialize();
registerShutdownHook(Neo4j.db());
}
}

Expand All @@ -44,9 +47,25 @@ public void enhance(ApplicationClass appClass) throws Exception {
public void onRoutesLoaded() {
if (Play.mode == Mode.DEV) {
// adding some route for
Logger.debug("adding routes for CAS Mock Server");
Logger.debug("adding routes for Neo4j plugin");
Router.addRoute("GET", "/@neo4j/import", "play.modules.neoj4.Import.execute");
}
}

/**
* Registers a shutdown hook for the Neo4j instance so that it shuts down nicely when the VM exits (even if you
* "Ctrl-C" the running example before it's completed)
*
* @param graphDb
*/
private static void registerShutdownHook(final GraphDatabaseService graphDb) {
Runtime.getRuntime().addShutdownHook(new Thread() {

@Override
public void run() {
graphDb.shutdown();
}
});
}

}
8 changes: 4 additions & 4 deletions src/play/modules/neo4j/annotation/Neo4jFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import models.relationship.EntityRelationType;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Neo4jFactory {

EntityRelationType root2ref();
Class clazz();

String root2ref();

EntityRelationType ref2node();
String ref2node();
}
39 changes: 31 additions & 8 deletions src/play/modules/neo4j/model/Neo4jModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.lang.reflect.Constructor;

import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Transaction;

import play.modules.neo4j.annotation.Neo4jEntity;
import play.modules.neo4j.annotation.Neo4jIndex;
Expand All @@ -23,18 +24,24 @@ public abstract class Neo4jModel {
* Unique id autogenerate by the factory
*/
@Neo4jIndex
public Long id;
public Long key;

/**
* underlying node of the model.
*/
private final Node underlyingNode;
public final Node underlyingNode;

/**
* Default constructor for creation.
*/
public Neo4jModel() {
this.underlyingNode = Neo4j.db().createNode();
Transaction tx = Neo4j.db().beginTx();
try {
this.underlyingNode = Neo4j.db().createNode();
tx.success();
} finally {
tx.finish();
}
}

/**
Expand All @@ -49,17 +56,18 @@ public Neo4jModel(Node underlyingNode) {
/**
* Getter for id.
*/
public Long getId() {
return (Long) this.underlyingNode.getProperty("id");
public Long getKey() {
return (Long) this.underlyingNode.getProperty("key", null);
}

/**
* Setter for id.
*
* @param id
*/
public void setId(Long id) {
this.underlyingNode.setProperty("id", id);
public void setKey(Long id) {
this.key = id;
this.underlyingNode.setProperty("key", id);
}

/**
Expand Down Expand Up @@ -90,6 +98,21 @@ public Neo4jModel save() throws Neo4jReflectionException {
throw new Neo4jReflectionException(e);
}
}
return null;
return this;
}

/**
* Method to delete orphelan node ... when garbage collector is running.
*/
protected void finalize() throws Throwable {
if (this.underlyingNode.hasRelationship() == false) {
Transaction tx = Neo4j.db().beginTx();
try {
this.underlyingNode.delete();
tx.success();
} finally {
tx.finish();
}
}
}
}
57 changes: 45 additions & 12 deletions src/play/modules/neo4j/model/Neo4jModelEnhancer.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package play.modules.neo4j.model;

import java.lang.annotation.Annotation;
import java.lang.reflect.Modifier;

import javassist.CtClass;
Expand All @@ -11,7 +12,6 @@
import play.Logger;
import play.classloading.ApplicationClasses.ApplicationClass;
import play.classloading.enhancers.Enhancer;
import play.classloading.enhancers.PropertiesEnhancer.PlayPropertyAccessor;
import play.exceptions.UnexpectedException;

/**
Expand All @@ -28,7 +28,7 @@ public void enhanceThisClass(ApplicationClass applicationClass) throws Exception
CtClass ctClass = makeClass(applicationClass);

// Only enhance Neo4jModel classes.
if (!ctClass.subtypeOf(classPool.get("play.modules.neo4j.Neo4jModel"))) {
if (!ctClass.subtypeOf(classPool.get("play.modules.neo4j.model.Neo4jModel"))) {
return;
}

Expand All @@ -52,11 +52,14 @@ public void enhanceThisClass(ApplicationClass applicationClass) throws Exception
}

String entityName = ctClass.getName();
Logger.debug("Enhance class " + entityName);

// for all field, we add getter / setter
for (CtField ctField : ctClass.getDeclaredFields()) {
try {
Logger.debug("Field " + ctField.getName() + " is a property ?");
if (isProperty(ctField)) {
Logger.debug("true");
// Property name
String propertyName = ctField.getName().substring(0, 1).toUpperCase()
+ ctField.getName().substring(1);
Expand All @@ -65,14 +68,15 @@ public void enhanceThisClass(ApplicationClass applicationClass) throws Exception

try {
CtMethod ctMethod = ctClass.getDeclaredMethod(getter);
if (ctMethod.getParameterTypes().length > 0 || Modifier.isStatic(ctMethod.getModifiers())) {
throw new NotFoundException("it's not a getter !");
}
ctClass.removeMethod(ctMethod);
throw new NotFoundException("it's not a true getter !");
} catch (NotFoundException noGetter) {

// Créé le getter
Logger.debug("Adding getter " + getter + " for class " + entityName);
String code = "public " + ctField.getType().getName() + " " + getter + "() { return ("
+ ctField.getType().getName() + ")this.underlyingNode.getProperty(\""
+ ctField.getName() + "\");}";
+ ctField.getName() + "\", null);}";
CtMethod getMethod = CtMethod.make(code, ctClass);
ctClass.addMethod(getMethod);
}
Expand All @@ -81,23 +85,35 @@ public void enhanceThisClass(ApplicationClass applicationClass) throws Exception
CtMethod ctMethod = ctClass.getDeclaredMethod(setter);
if (ctMethod.getParameterTypes().length != 1
|| !ctMethod.getParameterTypes()[0].equals(ctField.getType())
|| Modifier.isStatic(ctMethod.getModifiers())) {
throw new NotFoundException("it's not a setter !");
|| Modifier.isStatic(ctMethod.getModifiers())
|| hasPlayPropertiesAccessorAnnotation(ctMethod)) {
if (hasPlayPropertiesAccessorAnnotation(ctMethod)) {
ctClass.removeMethod(ctMethod);
}
throw new NotFoundException("it's not a true setter !");
}
} catch (NotFoundException noSetter) {
// Créé le setter
CtMethod setMethod = CtMethod.make("public void " + setter + "(" + ctField.getType().getName()
+ " value) { this.underlyingNode.setPrpoerty(" + ctField.getName() + ", value); }",
ctClass);
Logger.debug("Adding setter " + getter + " for class " + entityName);
CtMethod setMethod = CtMethod
.make("public void "
+ setter
+ "("
+ ctField.getType().getName()
+ " value) { org.neo4j.graphdb.Transaction tx = play.modules.neo4j.util.Neo4j.db().beginTx();try {this.underlyingNode.setProperty(\""
+ ctField.getName() + "\", value);tx.success(); } finally {tx.finish();}}",
ctClass);
ctClass.addMethod(setMethod);
createAnnotation(getAnnotations(setMethod), PlayPropertyAccessor.class);
}
}
} catch (Exception e) {
Logger.error(e, "Error in PropertiesEnhancer");
throw new UnexpectedException("Error in PropertiesEnhancer", e);
}
}
// Done.
applicationClass.enhancedByteCode = ctClass.toBytecode();
ctClass.defrost();

}

Expand All @@ -113,4 +129,21 @@ private boolean isProperty(CtField ctField) {
&& !Modifier.isStatic(ctField.getModifiers());
}

/**
* Is this method get PlayPropertiesAccessor annotation ?
*/
private boolean hasPlayPropertiesAccessorAnnotation(CtMethod ctMethod) {
for (Object object : ctMethod.getAvailableAnnotations()) {
Annotation ann = (Annotation) object;
Logger.debug("Annotation method is " + ann.annotationType().getName());
if (ann.annotationType().getName()
.equals("play.classloading.enhancers.PropertiesEnhancer$PlayPropertyAccessor")) {
Logger.debug("Method " + ctMethod.getName() + " has be enhanced by propertiesEnhancer");
return true;
}
}
Logger.debug("Method " + ctMethod.getName() + " has not be enhance by propertiesEnhancer");
return false;
}

}
Loading

0 comments on commit e7682c9

Please sign in to comment.