Errai has support for JAX-RS, although when I tried to use it with the supplied Maven archetype GWT complained with the error:
No source code is available for type javax.ws.rs.core.PathSegment; did you forget to inherit a required module?
The PathSegment interface appears to be part of the official Java EE standard, so why is this class not available?
A solution is to create the javax.ws.rs.core package in your GWT project, and include the interfaces for yourself. These interfaces are MultivaluedMap:
package javax.ws.rs.core;
import java.util.List;
import java.util.Map;
/**
* A map of key-values pairs. Each key can have zero or more values.
*
*/
public interface MultivaluedMap<K, V> extends Map<K, List<V>> {
/**
* Set the key's value to be a one item list consisting of the supplied value.
* Any existing values will be replaced.
*
* #param key the key
* #param value the single value of the key
*/
void putSingle(K key, V value);
/**
* Add a value to the current list of values for the supplied key.
* #param key the key
* #param value the value to be added.
*/
void add(K key, V value);
/**
* A shortcut to get the first value of the supplied key.
* #param key the key
* #return the first value for the specified key or null if the key is
* not in the map.
*/
V getFirst(K key);
}
PathSegment:
package javax.ws.rs.core;
/**
* Represents a URI path segment and any associated matrix parameters. When an
* instance of this type is injected with {#link javax.ws.rs.PathParam}, the
* value of the annotation identifies which path segment is selected and the
* presence of an {#link javax.ws.rs.Encoded} annotation will result in an
* instance that supplies the path and matrix parameter values in
* URI encoded form.
*
* #see UriInfo#getPathSegments
* #see javax.ws.rs.PathParam
*/
public interface PathSegment
{
/**
* Get the path segment.
* <p/>
*
* #return the path segment
*/
String getPath();
/**
* Get a map of the matrix parameters associated with the path segment.
* The map keys are the names of the matrix parameters with any
* percent-escaped octets decoded.
*
* #return the map of matrix parameters
* #see Matrix URIs
*/
MultivaluedMap<String, String> getMatrixParameters();
}
You'll need a GWT module file (in the javax.ws.rs package):
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 1.6//EN"
"http://google-web-toolkit.googlecode.com/svn/releases/1.6/distro-source/core/src/gwt-module.dtd">
<module rename-to="App">
<source path="core"/>
</module>
And you'll need to add an inherits reference to you application GWT module:
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 1.6//EN"
"http://google-web-toolkit.googlecode.com/svn/releases/1.6/distro-source/core/src/gwt-module.dtd">
<module rename-to="App">
<inherits name='com.google.gwt.user.User'/>
<inherits name="org.jboss.errai.common.ErraiCommon"/>
<inherits name="org.jboss.errai.ioc.Container"/>
<inherits name="org.jboss.errai.enterprise.Jaxrs"/>
<inherits name="com.redhat.topicindex.rest"/>
<inherits name="javax.ws.rs.core"/>
</module>
Related
Assuming I have a typedef type in a js module
// somewhere/foo.js
/**
* #module
*/
/**
* #typedef Foo
* #type {object}
* property {string} bar - some property
*/
Is it possible to reference this type in another module, so that in the HTML page generated by jsdoc, the type is displayed as a link to the typedef-ed module ?
I tried variations of this, but nothing seems to work...
// somewhere_else/bar.js
/**
* #module
*/
/**
* #param {somewhere/foo/Foo} foo - some param
*/
export default function doStuff(foo) {
...
}
This works for me ...
// somewhere/foo.js
/**
* #module foo
*/
/**
* #typedef module:foo.Foo
* #type {object}
* #property {string} bar - some property
*/
and ...
// somewhere_else/bar.js
/// <reference path="foo.js" />
/**
* #module bar
*/
/**
* #param {module:foo.Foo} foo - some param
*/
function doStuff(foo) {
//...
};
The above answer shows up high in search results so I'm documenting what worked for me in case it helps someone in a similar situation.
I'm using Visual Studio code for a node project with // #ts-check on all my modules. Using the above syntax hiccups on the module: syntax. Also, the code assistance doesn't work properly. It took me a while but the answer ended up being quite simple
If I have the typedef myTypedef in a module myModule then in the second module where I require myModule
mm = require(myModule)
I can use something like
/** #param {mm.myTypedef} myParamName */
The module syntax is not supported by TypeScript so if you're getting here assuming it to work, I haven't been able to get the solutions above to work.
To get it working with TypeScript use Import Types
For the OP the way I would do it is
// foo.d.ts
export type Foo = {
/**
* some property
*/
bar: string,
};
Then refer to it in the JS module as
/**
* #typedef { import("./foo").Foo } Foo
*/
/**
* #param {Foo} foo - some param
*/
export default function doStuff(foo) {
...
}
You can verify things are working on an individual file more strictly by adding the following to the beginning of the file. This will enable typescript checking in Visual Studio code for the specific file to help prepare your move to Typescript in the future.
// #ts-check
Many libraries export types from their root file, to access those in typedefs, change your import to use the import * as format.
For example:
import * as testingLibrary from '#testing-library/react';
/**
* #returns {testingLibrary.RenderResult}
*/
export function myCustomRender() { }
I've tried both of the above approaches.
Firstly, in the case of #typedef module:foo.Foo, VSCode treated the usage of Foo within the same file as any. Which I didn't find acceptable.
Secondly, when using ES6 imports the following issue emerges:
import foo from 'foo'
/** #param {foo.Foo} a - Error Foo does not exist on foo */
On the other hand VSCode recognizes import { Foo } from 'foo' without even using the JSDoc module syntax:
/**
* #module bar
*/
What's more I was also able to reference a property on the imported type, namely:
import { Foo } from 'foo'
/** #param {Foo['bar']} bar */
Note
This project uses Babel and assume compiling code which uses type imports in not feasible without a transpiler.
I'm working with vscode-powertools script which provides access to vscode module at runtime (as opposed to it being available to VSCode at edit time via the local node_modules).
If I would try to import the types with the usual jsdoc import
//#ts-check
/** #typedef {import('c:/Users/USERNAME/.vscode/extensions/ego-digital.vscode-powertools-0.64.0/node_modules/vscode').TextEditor} TextEditor */
I would be getting the File is not a module error:
File 'C:/Users/USERNAME/.vscode/extensions/ego-digital.vscode-powertools-0.64.0/node_modules/vscode/vscode.d.ts' is not a module. ts(2306)
So here's the trick I'm using to typecheck that kind of script:
//#ts-check
/// <reference types="c:/Users/USERNAME/.vscode/extensions/ego-digital.vscode-powertools-0.64.0/node_modules/vscode" />
// Allows us to reference the `vscode` module with jsdoc `#type`
async function vscodeⁱ() {if (1 == 1) return null; return import ('vscode')}
exports.execute = async (args) => {
// Allows us to reference the `vscode` module with jsdoc `#type`
const vscode = await vscodeⁱ()
/** #type {vscode} */
const vs = args.require ('vscode')
// NB: The following code is fully typed in VSCode
const windowᵛ = vs.window
const editorᵛ = windowᵛ.activeTextEditor
const start = editorᵛ.selection.start
}
I am new to zend 2 and Doctrine 2. I tried to create an entity class but got the following message:
Fatal error: Uncaught exception
'Doctrine\Common\Annotations\AnnotationException' with message
'[Semantical Error] The annotation "#Doctrine\ORM\Mapping\jobId" in
property Workers\Entity\Jobsought::$jobId does not exist, or could not
be auto-loaded
Below is the entity class
namespace Workers\Entity;
use Doctrine\ORM\Mapping as ORM;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\Factory as InputFactory;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFilterInterface;
/**
*
*
* #ORM\Entity
* #ORM\Table(name="worker_main_jobsort")
* #property int $jobId
*/
class Jobsought implements InputFilterAwareInterface
{
protected $inputFilter;
/**
* #ORM\jobId
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $jobId;
/**
* Magic getter to expose protected properties.
*
* #param string $property
* #return mixed
*/
public function __get($property)
{
return $this->$property;
}
/**
* Magic setter to save protected properties.
*
* #param string $property
* #param mixed $value
*/
public function __set($property, $value)
{
$this->$property = $value;
}
}
Any ideas why the ORM cannot map it? The table exist in my database.
Also just started out using the two of these combined - but think I know what your issue is.
First off, you can't try specifying any "strange" (according to doctrine strange) annotations without using the #ignore directive.
Secondly, I think you're trying to say with #property int $jobId that "$jobId" is your PK? Well you're already doing so when you say #ORM\GeneratedValue(strategy="AUTO"), telling doctrine to map jobid to be your PK. Also, I read somewhere that adding name="job_id" to your #Column annotation is good practice, but don't quote me on that. Guess it doesn't really matter.
Hope this helps!
Edit -
My bad, also missed that you need to remove #ORM\jobId as it's not a valid doctrine annotation (jobId that is). Just specify it as #ORM\Id and you should be fine.
I'm brand new to JSDoc, and I'm trying to figure out the best way to tag my code. For some reason after I label something as a #class, I can't get anything to appear as #inner:
/**
* The logger, to simply output logs to the console (or potentially a variable)
* #class Logger
* #requires 'config/globalConfig'
*/
define(["config/globalConfig"], function (config) {
/**
* Instantiate a new copy of the logger for a class/object
* #constructor
* #param name {string} - The name of the class instantiating the logger
*/
return function (name) {
/**
* #memberOf Logger
* #type {string}
*/
this.name = name;
/**
* Place the message on the console, only for "DEV" level debugging
* #function
* #memberOf Logger
* #param message {string}
*/
this.debug = function (message) {
... some code ...
};
};
});
Right now all the members are appearing as <static>. If I add the #inner tag to any of the attributes/functions they vanish completely from the output.
Edit: I also forgot to mention. The #constructor flag doesn't seem to be working either. If I remove that entire section, it appears the same in the output. The output does not include the #param that I would like to mention with my constructor.
Please let me know if this is completely off, I'm just kind of guessing here since the JSDoc3 documentation is a bit difficult to read.
So I figured it out, still not sure if it's absolutely correct. I had to use "Logger~name" to have it appear correctly as an inner function. According to the JSDoc documentation, this ~ is "rarely used". Seems to be the only thing that works for me.
define(["config/globalConfig"], function (config) {
/**
* The logger, to simply output logs to the console (or potentially a variable)
* #class Logger
* #param name {string} - The name of the class instantiating the logger
*/
return function (name) {
this.name = name;
/**
* Place the message on the console, only for "DEV" level debugging
* #function Logger~debug
* #param message {string}
*/
this.debug = function (message) {
... code ...
};
};
});
A symfony2 application has a Job entity that has as a property of type WebSite.
A simplified representation of this without other properties or methods:
/**
* #ORM\Entity
* #ORM\Table(name="Job")
*/
class Job
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="integer", name="website_id", nullable=false)
* #ORM\ManyToOne(targetEntity="Example\ExampleBundle\Entity\WebSite")
*/
protected $website;
}
Symfony/Doctrine is trying to cast the website property to a string when persisting resulting in the error:
Catchable Fatal Error: Object of class
Example\ExampleBundle\Entity\WebSite could not be converted to string
in /vendor/doctrine/dbal/lib/Doctrine/DBAL/Statement.php line 131
I believe the above #ORM\Column annotation denotes the website property to be an integer. I don't understand why Symfony/Doctrine wishes to try and convert the website property to a string.
Non-ideal workarounds I have tried in an attempt to resolve the matter:
Adding __toString() method to WebSite, returning a string representation of the id property, causes the correct value to ultimately end up in the Job.website_id datafield; this workaround is impractical as I will in the future need __toString() to be available to present a string elsewhere in the application.
Removing the #ORM\Column annotation from the website property; this results in all future diff-generated migrations (php app/console doctrine:migrations:diff) removing the 'not null' aspect of the relevant database field.
Are there any changes I should make to the above annotation to inform Symfony/Doctrine to call the getId() method of WebSite to get what it needs when persisting? Are there any changes I could make to WebSite to achieve the same?
What changes are required to ensure that the above annotation can remain in place such that Doctrine ultimately calls WebSite.getId() to get what it needs when persisting instead of trying to cast the object to a string?
You have to remove the #ORM\Column(type="integer" annotation from the $website property.
To be sure that the website_id column keeps the NOT NULL constraint, add a JoinColumn annotation with nullable=false in it:
/**
* #var Example\ExampleBundle\Entity\WebSite
*
* #ORM\ManyToOne(targetEntity="Example\ExampleBundle\Entity\WebSite")
* #ORM\JoinColumn(name="website_id", referencedColumnName="id", nullable=false)
*/
protected $website;
I use Acceleo in order to generate code with a model I have made. I managed to protect my methods in order to protect them usinig "#generated NOT" in case I need to regenerate my code with Acceleo. The problem is that adding #generated NOT protect all the method content, that is to say the body, the signature and JavaDocs.
The thing is that I only need to keep the method body, or at least the method body and its signature, but I need the doc to be updated. How can I do this ?
Just for information here is an example of a potential generated class :
/*
* #generated
*/
public class ActeurRefEntrepriseServicesImpl implements ActeurRefEntrepriseServices {
#Autowired
HelloWorldService helloWorldService;
/**
* Service which say hello
*
* #param name
* user name
* #return print Hello username
*
* #generated NOT
*/
#Override
public void sayHello(final String name) {
helloWorldService.print(name);
}
}
Baptiste,
The #generated tags use the standard EMF protection rules : "#generated" means that the body of the block for which it is set will be generated, anything else means no re-generation. If you set something as "#generated" in any of your metamodels' generated code, you will see that there, too, the javadoc is preserved whatever the edits you do.
In short, you cannot tell EMF to re-generate anything other than the code itself.
If you need to have the body protected but not the javadoc, you have to shift from the "#generated" protection to Acceleo's [protected] blocks. i.e, change your template from :
[template generatedMethod(methodName : String)]
/**
* Some doc.
* #param param1
* param documentation.
* #generated
*/
[generateSignature(methodName)/] {
[generateBody()/]
}
[/template]
to something using a protected block :
[template generatedMethod(methodName : String)]
/**
* Some doc.
* #param param1
* param documentation.
*/
[protected (methodName)]
[generateSignature(methodName)/] {
[generateBody()/]
}
[/protected]
[/template]
With this paradigm, anything that is outside of the protected area will be regenerated, everything else will remain untouched by a regeneration.
See also the full documentation available from the Acceleo website.
If you absolutely need to use the "#generated" protection method for your model, you will need to tamper with the JMerger API from EMF and alter the launcher Acceleo generated for you in order to use your own merging strategy (see the getGenerationStrategy method from that launcher). Note that this is by no means an easy task.