Initializing a (transient) EAttribute while parsing an Xtext resource - java

Let's say I have a simple Xtext rule
Hello: "Hello" name=STRING "!";
but in addition to the name EAttribute, my (previously existing) EClass Hello also has an EAttribute source of type EString (or an enum type, but for now let's assume an EString).
This field shall not be represented in the DSL itself (hence, it is transient in some way). Instead, I want to have this field set to "Xtext" when the object was read and instantiated by the Xtext parser. (I have other ways to create instances of Hello for which I set other values).
Is it possible to add something to my Hello: rule that sets the value of source automatically? Or do I have to intercept the parser somewhere?
I have found some notes about "actions" in Xtext grammars and I thought, maybe something like
Hello: { current.source = "Xtext" } "Hello" name=STRING "!";
would do the trick, but it seems these kinds of actions are not allowed ...

I have found a way by subclassing org.eclipse.xtext.parser.DefaultEcoreElementFactory and Guice-Injecting it as the org.eclipse.xtext.parser.IAstFactory for my language.
I override create() and do
EObject obj = super.create(...);
if(obj instanceof Hello)
((Hello)obj).setSource("Xtext");
return obj;
I don't know if this is the correct way, but it works.

Related

swagger-codegen simple models missing

I'm realizing my second API with swagger/swagger-codegen.
After having a really good start with my first one I'm somewhat stuck with the following problem:
I'm having multiple definitions like the following:
TopIssueReference:
description: Id of a top issue
type: string
example:
itemid: 'd32c1213-4773-442e-9c5f-f5d516358869'
All those definitions only are aliases for type string, some with format date-time, some naked like the one above.
The swagger editor is fine with those definitions.
When I use one of them in a $ref clause within some object definition the generator produces a reference to a class named like my definition, TopIssueReference in this case.
The generated TopIssueReference class is the following (in java):
#ApiModel(description = "Id of a top issue")
public class TopIssueReference {
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class TopIssueReference {");
sb.append("}");
return sb.toString();
}
}
which is not really useful.
Does anybody have an idea what's going wrong here?
Shouldn't the generator either produce a reference to a String or at least make TopIssueReference derive from a string (however useful that may be)?
For some of those definitions, the generator does not generate any class at all - but the references are still there, so the resulting code does not even compile.
I tried generating servers and clients with java and python, and both are having the same problem.
Try Bellow code to your swagger file to generate code.
TopIssueReference:
description: Id of a top issue
type: object
properties:
itemid:
type: string
i hope it's useful to you ...!

nameof equivalent in Java

C# 6.0 introduced the nameof() operator, that returns a string representing the name of any class / function / method / local-variable / property identifier put inside it.
If I have a class like this:
class MyClass
{
public SomeOtherClass MyProperty { get; set; }
public void MyMethod()
{
var aLocalVariable = 12;
}
}
I can use the operator like this:
// with class name:
var s = nameof(MyClass); // s == "MyClass"
// with properties:
var s = nameof(MyClass.OneProperty); // s == "OneProperty"
// with methods:
var s = nameof(MyClass.MyMethod); // s == "MyMethod"
// with local variables:
var s = nameof(aLocalVariable); // s == "aLocalVariable".
This is useful since the correct string is checked at compile time. If I misspell the name of some property/method/variable, the compiler returns an error. Also, if I refactor, all the strings are automatically updated. See for example this documentation for real use cases.
Is there any equivalent of that operator in Java? Otherwise, how can I achieve the same result (or similar)?
It can be done using runtime byte code instrumentation, for instance using Byte Buddy library.
See this library: https://github.com/strangeway-org/nameof
The approach is described here: http://in.relation.to/2016/04/14/emulating-property-literals-with-java-8-method-references/
Usage example:
public class NameOfTest {
#Test
public void direct() {
assertEquals("name", $$(Person.class, Person::getName));
}
#Test
public void properties() {
assertEquals("summary", Person.$(Person::getSummary));
}
}
Sadly, there is nothing like this. I had been looking for this functionality a while back and the answer seemed to be that generally speaking, this stuff does not exist.
See Get name of a field
You could, of course, annotate your field with a "Named" annotation to essentially accomplish this goal for your own classes. There's a large variety of frameworks that depend upon similar concepts, actually. Even so, this isn't automatic.
You can't.
You can get a Method or Field using reflection, but you'd have to hardcode the method name as a String, which eliminates the whole purpose.
The concept of properties is not built into java like it is in C#. Getters and setters are just regular methods. You cannot even reference a method as easily as you do in your question. You could try around with reflection to get a handle to a getter method and then cut off the get to get the name of the "property" it resembles, but that's ugly and not the same.
As for local variables, it's not possible at all.
You can't.
If you compile with debug symbols then the .class file will contain a table of variable names (which is how debuggers map variables back to your source code), but there's no guarantee this will be there and it's not exposed in the runtime.
I was also annoyed that there is nothing comparable in Java, so I implemented it myself: https://github.com/mobiuscode-de/nameof
You can simply use it like this:
Name.of(MyClass.class, MyClass::getProperty)
which would just return the String
"property"
It's also on , so you can add it to your project like this:
<dependency>
<groupId>de.mobiuscode.nameof</groupId>
<artifactId>nameof</artifactId>
<version>1.0</version>
</dependency>
or for Gradle:
implementation 'de.mobiuscode.nameof:nameof:1.0'
I realize that it is quite similar to the library from strangeway, but I thought it might be better not to introduce the strange $/$$ notation and enhanced byte code engineering. My library just uses a proxy class on which the getter is called on to determine the name of the passed method. This allows to simply extract the property name.
I also created a blog post about the library with more details.
Lombok has an experimental feature #FieldNameConstants
After adding annotation you get inner type Fields with field names.
#FieldNameConstants
class MyClass {
String myProperty;
}
...
String s = MyClass.Fields.myProperty; // s == "myProperty"

How to access method properties at compile-time?

I would like to access the usual reflection properties of a specific method without relying on Strings.
Is there any way to get from the method-Identifier to its reflection properties, like parameter types?
void run() {
java.lang.reflect.Method m = myMethod.getMethod(); // how?
Class<?>[] argClasses = m.getParameterTypes();
}
int myMethod(String arg) {
// ...
}
The piece myMethod.getMethod() is not valid. It is my way of saying "get from the method-identifier to the java.lang.reflect.Method object".
The string-way I do not want to use would be similar to m = getClass().getDeclaredMethod("myMethod", ...)
I use myMethod like a regular identifier and not as a String, i.e. "myMethod". I think this would be beneficial for refactoring, where someone renames myMethod to hisMethod -- the relation via the String-name would break, where the relation via the identifier would be refactored as well.
In java methods aren't first class citizens, so there is no solutions in Java for this problem.
Yet I had a similar problem and forged a small tool named picklock for this purpose.

How can I create an instance from a own class in FreeMarker (FTL)

I wish to instantiate a java class that I have defined in my domain and I want to use it from my FTL code in this way, but I'm getting an error.
<#assign myClassInstance = "com.domain.MyClass"?new())>
Is it possible? What I should change to do it?
MyClass doesn't implements the TemplateModel
Thanks!
There's no built-in function for instantiating arbitrary non-TemplateModel classes... maybe there should be a setting to allow that for ?new. Anyway, for now you can write a TemplateMethodModelEx that does that, and then you can pull that into some of your commonly included/imported templates like <#assign unrestrictedNew = "com.example.UnrestrictedNewMethodModel"?new()> (or just put the instance into the data-model or into the Configuration as a shared variable) and then you can do <#assign myClassInstance = unrestrictedNew("com.domain.MyClass")(arg1, arg2, argN)> in your templates. There are two tricky parts in implementing such a TemplateMethodModel. One is resolving the class name to a Class, for which I recommend env.getNewBuiltinClassResolver().resolve(className, env, null), where env is the current freemarker.core.Environment object. The other is calling the constructor, as then you have to convert parameter values and possibly chose an overloaded constructor. For that I recommend calling ow = env.getObjectWrapper(), see if ow instanceof BeansWrapper (throw exception if it isn't), then do return ((BeansWrapper) ow).newInstance(cl, arguments).

expression engine using groovy

I am trying to expose a expression engine built on top of groovy for end users. I have some excel style keywords and user can use variables within those keywords (which need to be substituted at runtime) for evaluation.
example, static keyword FIRSTCHAR(varName) will return the first character of a string. I have got this to work in a way.
Current Implementation
I have overridden the groovy class loader to create a compilation unit with an overridden PrimaryClassNodeOperation something like
class MyGroovyClassLoader extends GroovyClassLoader {
protected CompilationUnit createCompilationUnit(
CompilerConfiguration config, CodeSource source) {
CompilationUnit cu = super.createCompilationUnit(config, source);
cu.addPhaseOperation(new PrimaryClassNodeOperation(){
#Override
public void call(SourceUnit source, GeneratorContext context, ClassNode classNode)
throws CompilationFailedException {
source.getAST().getStatementBlock().visit(visitor);
}
}, Phases.SEMANTIC_ANALYSIS);
return cu;
}
}
The visitor then recognizes the static expression and variable expression. However, using this approach I am having difficulties in
1) Supporting variable names with dot (.) since dot is considered a property expression. Can I during this phase keep the property expression as variable expression.
2) Also, for an expression like (left(name,1)=='S' && right(name,1)=='n') [first character in name is s and last is n] - I want the equal to check to be single equals rather than double equals, and/AND instead of && or .and() so something like (left(name,1)='S' and right(name,1)='n')
What's the best way to achieve such customizations?
The best approach would be to use a custom parser (since you dont want your users to write any groovy) and then use groovy to actually implement the back-end
eg: Very indicative, your implementation can vary
(left(name,1)='S')
For the snipet above, tokens could be method:left, args:((var:name),(val:1)), exp:EQUALS, val:'S'
Have a map at the back which equates your tokens to groovy equivalents
You could then be fire your parsed tokens against a groovy class, of course the methods and arguments dont exist, use some groovy tricks to translate it to your actual implementation 1

Categories

Resources