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 ...!
Related
Short and sweet: despite the fact that I am asking the Javadoc API to give me the fully-qualified name of an annotation, it is only returning the simple type name.
I am writing a Javadoc doclet that relies heavily on the inspection of annotations. As such, I have created a utility function that will take an array of AnnotationDesc objects and return a Map that associates the fully-qualified name of the annotation to the AnnotationDesc object that describes it. Here are the relevant functions:
public static final Map<String, AnnotationDesc> getAnnotationMap(AnnotationDesc[] notes)
{
if (notes == null)
{
return Collections.emptyMap();
}
return Collections.unmodifiableMap(Arrays.stream(notes).collect(Collectors.toMap(AnnotationUtils::getNoteName, note -> note)));
}
private static String getNoteName(AnnotationDesc note) { return note.annotationType().qualifiedTypeName(); }
For what it's worth, I have also tried using qualifiedName, which is another method exposed by the return value of the AnnotationDesc.annotationType method.
In my integration tests, this is all working great. However, when I push my doclet out to Artifactory, pull it down into another project and try to invoke it by way of a Gradle task, the keys in my map are the simple type names of the annotations.
Here is the definition of my Gradle task:
task myDocletTask(type: Javadoc) {
source = sourceSets.main.allJava
destinationDir = reporting.file("my-doclet-dir")
options.docletpath = configurations.jaxDoclet.files.asType(List)
options.doclet = <redacted - fully qualified type name of custom doclet>
}
I have noticed that if a program element is annotated with a fully-qualified annotation, then the fully-qualified name is actually picked up by the Javadoc API. E.g: #com.package.Annotation results in the expected behavior, but #Annotation does not.
Can someone please help me to understand why this is happening and, more importantly, how I can achieve the expected/desired behavior?
The problem was that the annotations were not on the classpath of the doclet at "documentation time". In order to fix this problem I augmented my Gradle Javadoc task with the following line: options.classpath = sourceSets.main.runtimeClasspath.asType(List).
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"
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.
In an android application I'm developing I need to get a json file containing some data to reconstruct the lines of code of a java class.
Is there any java/javascript library that allows to convert/parse a java class (that doesn't just have fields, but also methods defined inside it) in JSON format, and vice-versa?
EDIT: I'd also need to keep track of the whole project's structure (something like antlr?)
EDIT2: My bad, I wanted to store a java class code into a JSON object to represent it, I was also thinking to create my own json object, this way, by parsing the Java code and finding methods, classes, parameters.
{
"file": "PATH/TO/.java",
"language": "java",
"from": 0,
"to": 255,
"classes": [
"Test:2"
//...
],
"lines": [
[
"public class Test{"
//...
]
]
}
But if a good starting point is present, that would be great.
The trouble is that existing tools (such as GWT) are "only" able to create functioning JS code that is meant to be executed in browsers. But it does not necessarily resemble the original Java class. Your use case sounds quite different. It looks like you want to represent Java source code as JSON data and you don't need/want to execute it.
I fear you may have to create your own tool for that, that meets your specific requirements. I also fear that this tool must be able to parse the Java code because using simple regexes for extracting the data won't help here much because of nested types (interfaces, classes, enums) and also because a single Java file may contain multiple type declarations (even though not encouraged, but it is possible).
Here are a few links for Java parsers:
http://code.google.com/p/javaparser/ (unfortunately only Java 1.5)
http://www.ibm.com/developerworks/opensource/library/os-ast/ (discusses the Eclipse Java parser which is very robust and probably most suitable for your requirement)
You could also create your own parser using ANTLR as you suggest. The latest ANTLR version has some visitor pattern you need to implement in Java, as far as I know. You could implement a visitor that successively constructs your JSON output.
However, you really should use Eclipse's ASTParser for that, because you can easily iterate all methods of your class and get their implementation code as String.
You can use jackson library - http://jackson.codehaus.org/: http://www.mkyong.com/java/how-to-convert-java-object-to-from-json-jackson/
Use GSON: "GOOGLE for JSON" it's a google open source JSON Library, it can convert Java Object t o JSON object and vice-versa
You have Gson package that convert Json String to Java object and vice versa.
MyClass.java
public class MyClass {
private String mStr = "";
public String getStr() {
return mStr;
}
public void setStr(String mStr) {
this.mStr = mStr;
}
}
Main.java
public class Main {
public static void main(String[] args) {
String jsonString = "{ \"mStr\": \"foo\" }";
Gson mGson = new Gson();
MyClass res = mGson.fromJson(jsonString, MyClass.class);
System.out.println(res.getStr());
}
}
Output: foo
[Edit 1]
You can't store to Json class structure, only data
[Edit 2]
From your fix I understand followed thing:
This Json String represents behavior what to do with "text" file , suppose, you download from server. But no mater what inside Json String 1st of all you need to convert it to Object in Java (if you want to use Java) and after that according to rules (took from Json String) write any logic. For sure java code is able to generate Java files. Your example tells you:
to get text from line ... to line,
create file named xxxx.java
copy it to ...
So use my example above, create class, lets say Launcher:
public class Launcher{
private String file;
private String language;
private int from;
private int to;
private List<String> classes;
private List<SomeOtherClass> lines;
....
}
I want to build tool support for the jape language from gate with the help of XText. Jape is basically a pattern language over annotations; you declare the actions to take when you encounter those annotations. The problem is that the actions can be written in java. After struggling with jdt for a while, I was unable to make it work over parts of the parsed content. So I gave up and decided to use the xbase support with XBlockExpression for that.
The problem is that there are some variables that can be used in the actions - for example there is a variable bindings which allows you to bind and then get annotations from the pattern. So my question is how to register those variables in the xblock scope. After reading the documentation for 3 hours I am still nowhere closer.
Here is a minimal grammar for my problem
grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.xbase.Xbase
generate myDsl "http://www.xtext.org/example/mydsl/MyDsl"
Model:
greetings=Greeting;
Greeting:
block=XBlockExpression;
I want to parse files with content like this:
{
val testAS = bindings.get("test") as AnnotationSet
}
I started by plugging in my own scope provider but that didn't help me much. Here is the implementation for the provider:
package org.xtext.example.mydsl;
import java.util.List;
public class MyScopeProvider extends XbaseScopeProvider {
XbaseFactory factory = new XbaseFactoryImpl();
#Override
public IScope getScope(EObject context, EReference reference) {
//System.err.println(context);
//System.err.println(reference);
List<IValidatedEObjectDescription> descriptions = Lists.newArrayList();
XVariableDeclaration variableDeclaration = factory
.createXVariableDeclaration();
variableDeclaration.setName("bindings");
IValidatedEObjectDescription variableDescription = createLocalVarDescription(variableDeclaration);
System.err.println(variableDescription);
IScope scope = super.getScope(context, reference);
System.err.println(variableDeclaration);
return new JvmFeatureScope(scope, "test", descriptions);
}
}
Any help will be appreciated
You should try to implement a JvmModelInferrer for your language where you add the implicitly available variables either as fields or operation arguments in the inferred type. That will do the trick. The approach is nicely documented in the 7 language examples on xtext.org