I' am trying to replace this code:
public void doThing(){
if(User.getInstance().isLoggin()){
.....
}
}
by this
#withUser
public void doThing(){
....
}
I saw about the interceptors and annotation, but I cannot do it.
Is this possible?
It is absolutely possible. Project Lombok provides the exact feature what you are looking for. You just need to create your own annotation by extending EclipseAnnotationHandler or JavacAnnotationHandler depending upon your requirement.
A sample annotation handler (WithUser) is given below for reference. If used on method, the entire method will become enclosed by if(false){...} block. Replace false with your own expression on Handler (HandleWithUser.java).
#WithUser
public void doThing(){
System.out.println("Hello World");
}
After annotation processing
public void doThing(){
if (false){
System.out.println("Hello World");
}
}
Setup Project Lombok
git clone https://github.com/rzwitserloot/lombok.git
cd lombok
ant eclipse
Open the Lombok project on Eclipse and create the following files.
WithUser.java
package lombok;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
#Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
#Retention(RetentionPolicy.SOURCE)
public #interface WithUser {
}
HandleWithUser.java
package lombok.javac.handlers;
import static lombok.javac.handlers.JavacHandlerUtil.setGeneratedBy;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.ast.IfStatement;
import org.eclipse.jdt.internal.compiler.ast.Statement;
import org.mangosdk.spi.ProviderFor;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
import com.sun.tools.javac.tree.JCTree.JCIf;
import com.sun.tools.javac.tree.JCTree.JCLiteral;
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
import com.sun.tools.javac.tree.JCTree.JCStatement;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.List;
import org.eclipse.jdt.internal.compiler.ast.FalseLiteral;
import lombok.WithUser;
import lombok.core.AnnotationValues;
import lombok.javac.JavacAnnotationHandler;
import lombok.javac.JavacNode;
import lombok.javac.JavacTreeMaker;
#ProviderFor(JavacAnnotationHandler.class)
public class HandleWithUser extends JavacAnnotationHandler<WithUser>{
#Override
public void handle(AnnotationValues<WithUser> annotationValues, JCAnnotation ast, JavacNode annotationNode) {
JavacNode annotation = annotationNode.up();
JCMethodDecl method = (JCMethodDecl)annotation.get();
List<JCStatement> contents = (List<JCStatement>) method.body.stats;
JCTree source = annotation.get();
JavacTreeMaker maker = annotationNode.getTreeMaker();
JCLiteral falseLiteral = maker.Literal(false);
JCIf ifStatement = maker.If(falseLiteral, maker.Block(0, contents), null);
Context context = annotationNode.getContext();
JCStatement ifBlock = setGeneratedBy(ifStatement, source, context);
method.body.stats = List.of(ifBlock);
annotation.rebuild();
}
}
Generate lombok.jar
ant dist
Test
Make sure you are including lombok.jar in classpath
javac -cp lombok.jar Test.java
For more info, visit https://projectlombok.org/contributing/contributing
Related
I Downloaded a kotlin file from github and wanted to convert it to a java file. I did this by Tools>Kotlin>Show kotlin ByteCode and then Decompiling. The Kotlin File is below:
package io.pokemon.core
import io.pokemon.model.Card
import io.pokemon.util.random.Randomiser
import io.pokemon.viewmodel.Round
class RoundFactoryImpl(private val randomiser: Randomiser) : RoundFactory {
override fun buildRound(cards: List<Card>): Round = Round()
}
After Copying the Decompiled kotlin Code into a java file I got the error: DefaultConstructorMarker is not public in kotlin.jvm.internal; cannot be accessed from outside package.
I attempted to fix this by adding the code inside DefaultConstructorMarker However this failed to fix the error.
package io.pokemon.core;
import io.pokemon.model.Card;
import io.pokemon.util.random.Randomiser;
import io.pokemon.viewmodel.Round;
import java.util.List;
import kotlin.Metadata;
import kotlin.jvm.internal.DefaultConstructorMarker;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;
#Metadata(
...
)
public final class RoundFactoryImpl implements RoundFactory {
private final Randomiser randomiser;
#NotNull
public Round buildRound(#NotNull List cards) {
Intrinsics.checkParameterIsNotNull(cards, "cards");
return new Round((List)null, (Card)null, 3, (DefaultConstructorMarker)null);
}
public RoundFactoryImpl(#NotNull Randomiser randomiser) {
super();
Intrinsics.checkParameterIsNotNull(randomiser, "randomiser");
this.randomiser = randomiser;
}
}
I have the following Junit test class
package Md5Tests;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
import timebackup.*;
/**
*
* #author jack
*/
public class PathNodeToXmlTest {
public PathNodeToXmlTest() {
}
#Before
public void setUp() {
}
#After
public void tearDown() {
}
#Test
public void createXml() {
PathNode root = new PathNode(true, "docs", "0");
root.addPathNode(new PathNode(true, "docs sub folder", "1"));
root.addPathNode(new PathNode(false, "docs sub file", "2"));
PathNodeToXml xmlCreator = new PathNodeToXml(root);
System.out.println(xmlCreator);
}
}
I am now trying to temporarily stop the test createXml() from being run by the test runner. I have tried adding the #Ignore annotation right before the #Test annotation however the compiler throws an error saying that it can't find the symbol for #Ignore. I am using the NetBeans Ide.
Anyone have any ideas either how to prevent the compile error, or another way to temporarily prevent a JUnit test from running?
#Ignore annotation is in a package org.junit so you need to add import statement
import org.junit.Ignore;
or
import org.junit.*;
Next time you have a problem like this you can just google class name (e.g. junit #Ignore) go to the documentation page and check package name.
In NetBeans you can use "Source -> Fix Imports" command (Ctrl + Shift + I) and IDE will try to resolve necessary imports automatically.
So, as I found the patched source code for BodyEditorLoader.java, I am not able to do any changes in the .java file. How to I edit it without destroying the library? Thanks!
I hope to explain well, a simple way would be to create a new class, copy the contents of the BodyEditorLoader class, except class package name package aurelienribon.bodyeditor;, and rename public class BodyEditorLoader by the name of your class, for example MyBodyEditorLoader. example:
//package aurelienribon.bodyeditor; --> change or delete for your packege name
package com.tynibattles04.game; //--> in your case for example.
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.CircleShape;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.JsonReader;
import com.badlogic.gdx.utils.JsonValue;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MyBodyEditorLoader {
//...other code
public MyBodyEditorLoader(FileHandle file) {
//...other code
}
public MyBodyEditorLoader(String str) {
//...other code
}
//..other code
and used (and import, if you need it necessary):
MyBodyEditorLoader loader = new MyBodyEditorLoader(
Gdx.files.internal("tankA.json"));
I just downloaded the play framework from their site and am working through this tutorial.
I've noticed the framework creates the folders app/controllers and app/views, but not a models folder. I created it manually and added Task.java to it. When I get to the section entitled "Rendering the first page" and open localhost:9000/tasks I get a compilation error that says package play.models does not exist. Here is what my Task.java looks like:
package models;
import java.util.*;
public class Task {
public Long id;
#Required
public String label;
public static List<Task> all() {
return new ArrayList<Task>();
}
public static void create(Task task) {
}
public static void delete(Long id) {
}
}
Here is application.java, the file generating the compilation error:
package controllers;
import play.*;
import play.mvc.*;
import views.html.*;
import play.data.*;
import play.models.*; // COMPILATION ERROR: "package play.models does not exist"!
public class Application extends Controller {
static Form<Task> taskForm = Form.form(Task.class);
public static Result index() {
//return ok(index.render("Your new application is ready."));
return redirect(routes.Application.tasks());
}
public static Result tasks() {
return ok(views.html.index.render(Task.all(), taskForm));
}
public static Result newTask() {
return TODO;
}
public static Result deleteTask(Long id) {
return TODO;
}
}
I believe it's supposed to be import models.Task; as opposed to import play.models.*;
That's quite confusing (IMHO) step in this tutorial, instead scroll down to Persist the tasks in a database section which describes preparing a model to cooperate with DB :) (it extends Model class, uses proper annotations, etc)
As you recognized it yet, you need to create a models package yourself.
Also as cYn wrote: you should import models like models.SomeModel into your controller
You are correct HukeLau_DABA , the Play will not create the models package for you. you have to create it.
I got these imports in my Application controller class. I got this sample play application running.
import play.api._
import play.api.mvc._
import play.api.data.Form
import play.api.data.Forms._
import models.Task
and another thing in Eclipse is it will not import the necessary imports automatically.
it is bit pain now, once the IDE support get better I hope this will change.
I want to make use of the new functionality in the latest build of junit in order to name my parameterized tests
I have the following two tests written in java & scala, but the scala test generates a compiler error:
error: unknown annotation argument name: name #Parameters(name =
"{0}") def data: util.Collection[Array[AnyRef]] =
util.Arrays.asList(Array("x"), Array("y"), Array("z"))
What is the difference in implementation causing this error?
java
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import java.util.Arrays;
import java.util.Collection;
import static org.junit.Assert.fail;
#RunWith(Parameterized.class)
public class ParameterizedTest {
#Parameters(name = "{0}")
public static Collection<Object[]> data() {
return Arrays.asList(new Object[]{"x"}, new Object[]{"y"}, new Object[]{"z"});
}
#Test
public void foo() {
fail("bar");
}
}
scala
import java.util
import org.junit.Assert._
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
import org.junit.runners.Parameterized._
#RunWith(classOf[Parameterized])
class ParameterizedScalaTest {
#Test def foo() {
fail("bar")
}
}
object ParameterizedScalaTest {
#Parameters(name = "{0}") def data: util.Collection[Array[AnyRef]] = util.Arrays.asList(Array("x"), Array("y"), Array("z"))
}
Because #Parameters is defined as an inner, you seem to need to give the full name.
Try
#Parameters(Parameters.name = "{0}")
At least, that is the only significant difference I can observe in the definitions of #Parameters and #Test, and this works:
#Test(timeout = 10)
It turns out the issue here is due to junit-dep.jar being on the classpath through a transient dependency on jMock 2.4.0
Removing that fixed the compiler error, odd that this is an issue for scalac but not javac.