In groovy, when I want to create a property with public-read but protected-write access, I need to write the following code (as per the Groovy Docs):
class SomeClass {
/**
* Public property
*/
String someProperty
/**
* Make it protected-write
*/
protected void setSomeProperty(String someProperty) { this.someProperty = someProperty }
}
Is there a short-hand for this? Something like:
class SomeClass {
#Protected String someProperty
}
There should also be a #Private annotation along the same lines.
Note
These annotations would only affect the setter method of the property. This should allow any required access-level combination i.e.:
/** An entirely protected property */
protected String someProperty
/** An entirely private property */
private String someProperty
/** A read-only property */
final String someProperty
/** Private-Setter, Protected-Getter */
#Private protected String someProperty
There is not any shorthand way to express that, at least not in default Groovy. You could write an AST transformation which imposes rules like those you describe but Groovy does not do anything like that by default.
I hope that helps.
Related
I am very new to nodejs and typescript.
I have try to provide an API via express.
I have try to return a custom object on my API who looks like that :
export class Auction {
private _currentPrice:number = 0;
private _auctionName:string;
public constructor(currentPrice: number , auctionName: string) {
this._currentPrice = currentPrice;
this._auctionName = auctionName;
}
/**
* Getter auctionName
* #return {string}
*/
public get auctionName(): string {
return this._auctionName;
}
/**
* Setter auctionName
* #param {string} value
*/
public set auctionName(value: string) {
this._auctionName = value;
}
/**
* Setter currentPrice
* #param {number } value
*/
public set currentPrice(value: number ) {
this._currentPrice = value;
}
/**
* Getter currentPrice
* #return {number }
*/
public get currentPrice(): number {
return this._currentPrice;
}
}
But what I have seen is that the answer of my API is something like :
{"_currentPrice":0,"_auctionName":"toto"}
I was expecting something like
{"currentPrice":0,"auctionName":"toto"}
Is there any way to automaticaly convert it to the format I want ?
This is happening because when the TypeScript is compiled to JavaScript, objects created by that class have public _currentPrice and _auctionName properties (because TypeScript "private" properties are only private in terms of TypeScript's type system) and they don't have their own currentPrice and auctionName properties (they inherit them from their prototype, which has them as accessor properties). JSON.stringify only includes "own" properties.
You can deal with it in a few ways:
By using simple properties for currentPrice and auctionName. You have public accessors for both get and set for both properties, so there doesn't seem to be any reason to use private properties to hold their values. Or,
By providing your own toJSON method for the class:
toJSON() {
return {currentPrice: this._currentPrice, auctionName: this._auctionName};
}
Despite the name "toJSON", this method isn't supposed to return JSON; it's supposed to return the value for the object that should be converted to JSON. So in this case, you return an object with the properties you want the returned JSON to have.
A third solution would be to use JavaScript's own private properties (they're supported in up-to-date Node.js versions) and "own" accessors for them on the objects, but I don't think TypeScript supports JavaScript's private properties yet.
I am trying to use JAXB in an Eclipse project. View widgets are bound to model attributes with java.beans.PropertyChangeSupport. This works fine. I want to also bind model attributes to a persistent XML representation on disk with JAXB. I can marshal important state to XML and can unmarshal that back into a pojo/bean thing at runtime but am not sure how best to proceed.
The bean setters bound to my view widgets need to firePropertyChange() but XJC generates only simple setters, this.value = value.
XJC properties are protected, so it looks like I could override its setters to firePropertyChange(), but I don't know how my overriding subclass could have its unmarshaled superclass magically change state at runtime (like when user requests report for different year which is when I would unmarshal a different XML file).
Is there an example or pattern for doing this? Surely it is not new. Many thanks. -d
#Adam Thanks! I grokked a workable solution with this:
public class MyBean extends JaxBean {
public JaxBean getJaxBean() {
return this;
}
public void setJaxBean(JaxBean jaxBean) {
super.setThis(jaxBean.getThis());
super.setThat(jaxBean.getThat());
// etc...
}
public MyBean() {
// etc...
}
}
I think my confusion was thinking the unmarshalled bean would somehow magically replace my working instance. The solution above requires additional text but it works and the use of JaxBean's dumb setters avoids firing events unnecessarily when loading a new XML.
Your solution, annotating MyBean with JAXB and using schemagen, sounds even better. I will try that next go around. These are very nice technologies. -d
I mentioned another approach to your application in my comment.
It's what we use in our RCP application. Except that we marshall/unmarshall through network thus we use JAXWS and not just JAXB.
I'm somewhat experienced with this kind of stack, so here's a kick-starter for you:
/**
* Your UI POJO-s should extend this class.
*/
public abstract class UIModel<T extends UIModel> {
protected final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
/**
* This comes handy at times
*/
public void afterUnmarshal(Unmarshaller unmarshaller, Object parent) {
//....
}
/**
* And this too, trust me.
*/
public void deepCopy(final T of) {
removePropertyChangeListener(propertyChangeListener);
//It's from Spring Framework but you can write your own. Spring is a fat-ass payload for a Java-SE application.
BeanUtils.copyProperties(of, this, IGNORED_ON_CLIENT);
addPropertyChangeListener(propertyChangeListener);
}
}
public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(propertyName, listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.removePropertyChangeListener(listener);
}
}
/**
* Example of a UI POJO.
*/
public class Car extends UIModel<Car> {
private String make;
private int numberOfWheels;
//... etc.
/**
* Example of a setter
*/
public void setMake(String make) {
propertyChangeSupport.firePropertyChange("make", this.make, this.make = make);
}
public String getMake() {
return make;
}
//... etc.
}
I don't know how often your Schema-definition changes but there's a pattern supporting this;
/**
* New application (compiled with the class below) can open a file saved by the old application.
*/
public class Car2 extends Car {
private String fuelType; // Example of a new field
public void setFuelType(String fuelType) {
propertyChangeSupport.firePropertyChange("fuelType", this.fuelType, this.fuelType = fuelType);
}
//... etc.
}
This way the old application can open XML-outputs of the new. Dropping a field from such a class's source code will result in a RuntimeException as JAXB is still looking for it.
If you're clients are always up-to-date then you should not care about this at all.
When tackling with Java collections and subclassing excessively you will run into JAXB problems which you can solve by Googling #XmlRootElement and #XmlSeeAlso annotations.
Comments don't format, trying "answer". Need to do the stackoverflow tour. Continuing,
Thanks, Adam, I will bookmark these for future reference. They look similar to my example, the pattern is (unmarshal New, be quiet, copy New to Old, be noisy). I like the mind-bending recursion,
class UIModel<T extends UIModel>
class Car extends UIModel<Car>
and assume you've tested it compiles. ;)
Regards, -d.
I've started looking into Groovy, and I've some mixed feelings about how class arguments are defined. By default, they include getter and setter, but what if I don't want to have a setter? What is the way to restrict to only allowing to get a value of a property? In C# it can be done like this:
public double Hours
{
get { return seconds / 3600; }
}
If I'm not mistaken.
If you declare the property as final, a setter won't be created.
Or, if you declare your own private/protected setter, then a public one won't be created.
So, as in your example:
Integer hours
private void setHours(Integer hours) {}
Or:
final Integer hours
One way is to Metaprogramming feature of Groovy. In this case overrides
setProperty(String name, Object value) method to intercept the setter calls and trow exception instead.
class A {
String a
String b
void setProperty(String name, Object value){
throw new IllegalAccessError()
}
}
This also works with getter as well by override def getProperty(String name).
In groovy once field is created, it will be by default public , setter and getter will be created.
So You can declare your own setter or getter and specify the access level, in this case, the default one will not be created.
example :
private void setHours(Integer hours) {
seconds * 3600
}
Using Symfony2 / doctrine2, while we use the find() function to get a specific object based on the entity selected if there are relations (like OneToMany), Doctrine return all other object.
For example :
$em = $this->get(
'doctrine.orm.entity_manager',
$request->getSession()->get('entity_manager')
);
$product = $em->getRepository('MyBundle:Product')->find($id);
The result on $product will be the Product object + other linked objects like (Store, Category, ...etc.)
How can we control doctrine to determinate which object we need to be returned.
I can use Querybuilder, but i am looking if there are any function all determinate.
Doctrine return all other object
This is not how it works, at least by default.
Doctrine uses what is called lazy loading.
From the official documentation, you have the following example:
<?php
/** #Entity */
class Article
{
/** #Id #Column(type="integer") #GeneratedValue */
private $id;
/** #Column(type="string") */
private $headline;
/** #ManyToOne(targetEntity="User") */
private $author;
/** #OneToMany(targetEntity="Comment", mappedBy="article") */
private $comments;
public function __construct {
$this->comments = new ArrayCollection();
}
public function getAuthor() { return $this->author; }
public function getComments() { return $this->comments; }
}
$article = $em->find('Article', 1);
And the following explanation:
Instead of passing you back a real Author instance and a collection of
comments Doctrine will create proxy instances for you. Only if you
access these proxies for the first time they will go through the
EntityManager and load their state from the database.
Reference: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/working-with-objects.html#entity-object-graph-traversal
More information about the topic: http://www.doctrine-project.org/blog/doctrine-lazy-loading.html
You can configure extra lazy associations to avoid loading of relations in general.
/**
* #ManyToMany(targetEntity="CmsUser", mappedBy="groups", fetch="EXTRA_LAZY")
*/
protected $property;
For the follwing example XML input:
<Participants course="someCourse">
<workers>
<Worker ref="p3">
<Worker ref="p2">
</workers>
<Trainer ref="p1"/>
</Participants>
<Group id="group1" name="some mixed Person group">
<trainers>
<Trainer id="p1" name="John Doe">
</trainers>
<workers>
<Worker id="p2" name="Jim Scott">
<Worker id="p3" name="Walter Peace">
</workers>
</Group>
I am trying to make sure that the PersonList in Participants points to the Persons read from group1. (see code snipptes below for the JaxB annotations used). This is just an example for the more generic
approach I am seeking. I need to be generally able to follow id="" and ref="" attributes in a way
that the list elements are correctly unmarshalled as references.
With an UnmarshalListener and Unmarshalling twice I get around the problem of the references from the ref attribute to the id attribute. In the first phase the lookup Map is filled from the id attributes. In the second phase the refs are looked up. Unfortunately this solution will create copies instead of references. I could use the parent object to fix this but I am looking for a more generic solution. What would be a good way to achieve the proper dereferencing using ref/id attributes in the manner shown?
/**
* intercept the unmarshalling
*/
public static class ModelElementMarshallerListener extends javax.xml.bind.Unmarshaller.Listener {
public Map<String,Person> lookup=new HashMap<String,Person>();
#Override
public void afterUnmarshal(java.lang.Object target, java.lang.Object parent) {
if (target instanceof Person) {
person=(Person) target;
if (person.getId()!=null) {
lookup.put(person.getId(), person);
}
if (person.getRef()!=null) {
if (lookup.containsKey(person.getRef())) {
Person personRef=lookup.get(person.getRef());
person.copyFrom(personRef);
person.setRef(null);
}
}
}
}
}
#XmlRootElement(name="Participants")
public class Participants {
private List<Worker> workers;
/**
* getter for List<Worker> workers
* #return workers
*/
#XmlElementWrapper(name="workers")
#XmlElement(name="Worker", type=Worker.class)
public List<Worker> getWorkers() {
return workers;
}
...
}
#XmlRootElement(name="Group")
public class Group {
private List<Worker> workers;
/**
* getter for List<Worker> workers
* #return workers
*/
#XmlElementWrapper(name="workers")
#XmlElement(name="Worker", type=Worker.class)
public List<Worker> getWorkers() {
return workers;
}
...
}
#XmlRootElement(name="Trainer")
public class Trainer extends Person {}
#XmlRootElement(name="Worker")
public class Worker extends Person {}
#XmlRootElement(name="Person")
public class Person {
private String name;
/**
* getter for xsd:string/String name
* #return name
*/
#XmlAttribute(name="name")
public String getName() {
return name;
}
public void setName(String name) {
this.name=name;
}
private String ref;
/**
* getter for xsd:string/String id
* #return id
*/
#XmlAttribute(name="ref")
public String getRef() {
return ref;
}
public void setRef(String ref) {
this.ref=ref;
}
private String id;
/**
* getter for xsd:string/String id
* #return id
*/
#XmlAttribute(name="id")
#XmlID
public String getId() {
this.id;
}
/**
* setter for xsd:string/String id
* #param pid - new value for id
*/
public void setId(String pid) {
this.id=pid;
}
}
To better illustrate the point I have modified the question to fit his answer. There is now a generic base class Person and I am trying to use it as per Can generic XmlAdapter be written
I solved the issue of being able to actually make sure the Adapters are used by writing specific derived Classes and using them with #XmlJavaTypeAdapter. I preregister the adapters using:
JAXBContext context = JAXBContext.newInstance(type);
Unmarshaller u = context.createUnmarshaller();
u.setAdapter(Worker.WorkerAdapter.class,new Worker.WorkerAdapter());
u.setAdapter(Trainer.TrainerAdapter.class,new Trainer.TrainerAdapter());
and then unmarshalling twice. The debug shows that the Adapter instance for both passes is the same. Still the lookup somehow seemed to fail ... The reason was the way the #XmlJavaTypeAdapter annotation works see:
What package-info do I annotate with XmlJavaTypeAdapters?
There seem to be multiple modes for #XmlJavaTypeAdapter:
it can be an annotation for a class
it can be an annotation for a field (getter)
it can be used in a package-info.java file to annotate a whole package
At this point I am using all three annotations and now have to debug which ones are necessary. I assume the global annotations (class,package) are not working as expected. The reason might be the type= usage in the #XmlElementWrapper which explicitly calls for a type. Personally I do not understand what is going on yet. At least things are now working as expected.
the local field annotation is now e.g.:
#XmlElementWrapper(name="workers")
#XmlElement(name="Worker", type=Worker.class)
#XmlJavaTypeAdapter(WorkerAdapter.class)
the package-info.java annotation is:
#XmlJavaTypeAdapters({
#XmlJavaTypeAdapter(value=WorkerAdapter.class,type=Worker.class),
#XmlJavaTypeAdapter(value=TrainerAdapter.class,type=Trainer.class),
})
package com.bitplan.jaxb.refidtest;
import javax.xml.bind.annotation.adapters.*;
the class annotation is:
#XmlJavaTypeAdapter(Worker.WorkerAdapter.class)
public class Worker extends Person {
...
/**
* Worker Adapter
* #author wf
*
*/
public static class WorkerAdapter extends PersonAdapter<Worker>{
#Override
public Worker marshal(Worker me)
throws Exception {
return super.marshal(me);
}
#Override
public Worker unmarshal(Worker me) throws Exception {
return super.unmarshal(me);
}
}
/**
* https://stackoverflow.com/questions/7587095/can-jaxb-marshal-by-containment-at-first-then-marshal-by-xmlidref-for-subsequen/7587727#7587727
* #author wf
*
*/
public class PersonAdapter<T extends Person> extends XmlAdapter<T, T>{
public boolean debug=true;
/**
* keep track of the elements already seen
*/
public Map<String,T> lookup=new HashMap<String,T>();
#Override
public T marshal(T me)
throws Exception {
return me;
}
/**
* show debug information
* #param title
* #param key
* #param me
* #param found
*/
public void showDebug(String title,String key,T me, T found) {
String deref="?";
if (found!=null)
deref="->"+found.getId()+"("+found.getClass().getSimpleName()+")";
if (debug)
System.err.println(title+": "+key+"("+me.getClass().getSimpleName()+")"+deref+" - "+this);
}
#Override
public T unmarshal(T me) throws Exception {
if (me.getId()!=null) {
showDebug("id",me.getId(),me,null);
lookup.put(me.getId(), me);
return me;
}
if (me.getRef()!=null) {
if (lookup.containsKey(me.getRef())) {
T meRef=lookup.get(me.getRef());
showDebug("ref",me.getRef(),me,meRef);
me.setRef(null);
return meRef;
} else {
if (debug)
showDebug("ref",me.getRef(),me,null);
}
}
return me;
}
}