Vala: D-BUS object implementing interface, error with properties - interface

Is it possible to have a class annotated with [DBus (name = ...)] implement an interface?
Following the example at https://live.gnome.org/Vala/DBusServerSample, I am implementing a D-BUS client/server application.
One thing that I found peculiar about the example was that there was no separate interface definition. I would like to have the interface used by the client side in a separate file, and have the server class implement that interface. That way I can have the compiler tell me when I miss something.
This does not appear to work with properties though. The following definition is compatible with what I have:
/* interface.vala */
namespace org.test {
[DBus (name = "org.test.Items")]
public interface IItems : Object {
/**
* The object paths to the item instances.
*
* These objects are of type org.test.items.Item.
*/
public abstract ObjectPath[] items {
owned get;
}
/**
* The signal that is emitted when a new item is added.
*
* When this signal is emitted, the item will be available.
*
* #param id
* The object path to the item instance.
*/
public signal void item_added(ObjectPath id);
/**
* The signal that is emitted when an item is removed.
*
* When this signal is emitted, the item will be unavailable.
*
* #param id
* The object path to the item instance.
*/
public signal void item_removed(ObjectPath id);
/**
* Adds a new item.
*
* The URL will be parsed, and if it contains a valid item, it will be
* added.
*
* #param url
* The URL to the item. This should typically be the URL of the
* RSS feed.
* #return the ID of the item added, which can be used to query D-BUS
* for it
* #throws IOError if a D-BUS error occurs
*/
public abstract ObjectPath add_item(string url) throws IOError;
/**
* Removes an item.
*
* #param id
* The ID of the item to remove.
* #throws IOError if a D-BUS error occurs
*/
public abstract void remove_item(ObjectPath id) throws IOError;
}
}
/* server.vala */
using Gee;
namespace org.test {
[DBus (name = "org.test.Items")]
public class Items : DBUSObject, IItems {
private ArrayList<Item> _items;
[DBus (visible = false)]
protected override void dbus_register(DBusConnection conn,
ObjectPath path) throws IOError {
conn.register_object(path, this);
}
[DBus (visible = false)]
public Items() {
base("org.test.Items", "/org/test", "Items", true);
_items = new ArrayList<Item>();
}
[DBus (visible = false)]
~Items() {
unregister();
}
/**
* #see interface.vala::org.test.IItems.comics
*/
public ObjectPath[] items {
owned get {
ObjectPath[] result = {};
foreach (var item in _items) {
result += new ObjectPath(item.path);
}
return result;
}
}
/**
* #see interface.vala::org.test.IItems.add_comic
*/
public ObjectPath add_item(string url) throws IOError {
/* . . . */
}
/**
* #see interface.vala::org.test.IItems.remove_item
*/
public void remove_item(ObjectPath id) throws IOError {
/* . . . */
}
}
}
When I compile it, I get no error from valac, but when the generated C code is compiled, the linker complains: undefined reference to 'org_test_items_get_items'.
This function is referenced by _dbus_org_test_items_get_items, but it does not exist

It's obviously a bug. The right place to report bugs is http://bugzilla.gnome.org .

Related

Symfony 3.0.4 Circular reference detected during serialization with FOSRestBundle

I'm using FOSRestBundle in a Symfony project. When it I try to handle a view, it fails during the serialization of my data with the Symfony serializer as well as with the JMSSerializer.
This is the method rendering the response:
DefaultController.php
$em = $this->getDoctrine()->getManager('magellan');
$qb = $em->createQueryBuilder();
$query = $qb->select('h')
->from('DataBundle:Holding', 'h')
->where($qb->expr()->eq('h.id', ':holding_id'))
->setParameter('holding_id', $holding_id)
->getQuery();
$results = $query->getResult();
$view = $this->view($results, 200);
// Everything's ok up to this point
return $this->handleview($view);
And these are my entities:
Holding.php
class Holding
{
...
/**
* #ORM\OneToMany(targetEntity="Subsidiary", mappedBy="holding")
*/
private $subsidiaries;
}
Subsidiary.php
class Subsidiary
{
...
/**
* #ORM\ManyToOne(targetEntity="Holding", inversedBy="subsidiaries")
* #ORM\JoinColumn(name="id_holding", referencedColumnName="id_holding")
*/
private $holding;
/**
* #ORM\OneToMany(targetEntity="Brand", mappedBy="subsidiary")
*/
private $brands;
}
Brand.php
class Brand
{
...
/**
* #ORM\ManyToOne(targetEntity="Subsidiary", inversedBy="brands")
* #ORM\JoinColumn(name="id_subsidiary", referencedColumnName="id_subsidiary")
*/
private $subsidiary;
/**
* #ORM\OneToMany(targetEntity="Product", mappedBy="brand")
*/
private $products;
}
Product.php
class Product
{
...
/**
* #ORM\ManyToOne(targetEntity="Brand", inversedBy="products")
* #ORM\JoinColumn(name="id_brand", referencedColumnName="id_brand")
*/
private $brand;
/**
* #ORM\ManyToOne(targetEntity="Sector", inversedBy="products")
* #ORM\JoinColumn(name="id_sector", referencedColumnName="id_sector")
*/
private $sector;
/**
* #ORM\OneToMany(targetEntity="Commercial", mappedBy="product")
*/
private $commercials;
}
Commercial.php
class Commercial
{
...
/**
* #ORM\ManyToOne(targetEntity="Product", inversedBy="commercials")
* #ORM\JoinColumn(name="id_product", referencedColumnName="id_product")
*/
private $product;
/**
* #ORM\OneToMany(targetEntity="CommercialReport", mappedBy="commercial")
*/
private $reports;
CommercialReport.php
class CommercialReport
{
...
/**
* #ORM\ManyToOne(targetEntity="Commercial", inversedBy="reports")
* #ORM\JoinColumn(name="id_commercial", referencedColumnName="id_commercial")
*/
private $commercial;
}
Sector.php
class Sector
{
...
/**
* #ORM\OneToMany(targetEntity="Product", mappedBy="sector")
*/
private $products;
}
When using the default symfony serializer, I get the following error:
"message":"A circular reference has been detected (configured limit:
1).","class":"Symfony\Component\Serializer\Exception\CircularReferenceException"
And when using the JMSSerializer, when I go to the corresponding page of the controller, the page just never finishes loading. At the same time in the dev.log file new Doctrine.debug entries with requests to my DB are added every second.
$normalizers->setCircularReferenceHandler(function ($object) {
return $object->getId();
});
Just add it after you make the instance if your objectNormalizer()
it worl perfectly for me
If you use FosRestBundle, you can use the GROUPS for the serializer. There is an annotation given by FosRestBundle : #FOS\RestBundle\Controller\Annotations\View(serializerGroups={"user"})
Your group can exclude the circular property.
Another idea you can do this. In your app/config/services.yml
circular_reference_handler:
public: false
class: callback
factory: [AppBundle\Serializer\CircularHandlerFactory, getId]
serializer.normalizer.object:
class: Symfony\Component\Serializer\Normalizer\ObjectNormalizer
arguments: ["#serializer.mapping.class_metadata_factory", null, "#serializer.property_accessor"]
public: false
tags: [serializer.normalizer]
calls:
- method: setCircularReferenceLimit
arguments: [1]
- method: setCircularReferenceHandler
arguments: ["#circular_reference_handler"]
The factory can be like this:
namespace AppBundle\Serializer;
class CircularHandlerFactory
{
/**
* #return \Closure
*/
public static function getId()
{
return function ($object) {
return $object->getId();
};
}
}

Error with to string method my code is below

Trying to code this and its driving me crazy i know its something simple
my question is on the toString method i am getting compile error Cannot find symbol varible getNext also if you can check the rest of the methods for accuracy that would be greatly appreciated
public class Turner_A06Q2
{
/**
* Program entry point for queue testing.
* #param args Argument list.
*/
public static void main(String[] args)
{
LinkedQueue<Integer> queue = new LinkedQueue<Integer>();
System.out.println("QUEUE TESTING");
queue.enqueue(3);
queue.enqueue(7);
queue.enqueue(4);
System.out.println(queue.first());
queue.dequeue();
queue.enqueue(9);
queue.enqueue(8);
System.out.println(queue.first());
System.out.println(queue.dequeue());
System.out.println(queue.first());
System.out.println("The size of the queue is: " + queue.size());
System.out.println("The queue contains:\n" +queue.toString());
}
/**
* LinkedQueue represents a linked implementation of a queue.
*
* #author Java Foundations
* #version 4.0
*/
public static class LinkedQueue<T> implements QueueADT<T>
{
private int count;
private LinearNode<T> head, tail; //front, back
/**
* Creates an empty queue.
*/
public LinkedQueue()
{
count = 0;
head = tail = null;
}
/**
* Adds the specified element to the tail of this queue.
* #param element the element to be added to the tail of the queue
*/
public void enqueue(T element)
{
LinearNode<T> node = new LinearNode<T>(element);
if (isEmpty())
head = node;
else
tail.setNext(node);
tail = node;
count++;
}
/**
* Removes the element at the head of this queue and returns a
* reference to it.
* #return the element at the head of this queue
* #throws EmptyCollectionException if the queue is empty
*/
public T dequeue() throws EmptyCollectionException
{
if (isEmpty())
throw new EmptyCollectionException("queue");
T result = head.getElement();
head = head.getNext();
count--;
if (isEmpty())
tail = null;
return result;
}
/**
* Returns a reference to the element at the head of this queue.
* The element is not removed from the queue.
* #return a reference to the first element in this queue
* #throws EmptyCollectionsException if the queue is empty
*/
public T first() throws EmptyCollectionException
{
return head.getElement();
return null;
}
/**
* Returns true if this queue is empty and false otherwise.
* #return true if this queue is empty
*/
public boolean isEmpty()
{
return count==0;
}
/**
* Returns the number of elements currently in this queue.
* #return the number of elements in the queue
*/
public int size()
{
return count;
return 0;
}
/**
* Returns a string representation of this queue. The front element
* occurs first, and each element is separated by a space. If the
* queue is empty, returns "empty".
* #return the string representation of the queue
*/
public String toString()
{
if (isEmpty()) {
return " ";
}
StringBuilder sb = new StringBuilder();
LinearNode<T> next = head.getNext;
while(next != null){
sb.append(" ").append(next.getElement());
next = next.getNext();
}
return sb.toString();
}
}
}
it is a queue and you are trying to print the contents of a queue without actually iterating over it hence, the error.
Try something like this:
for (E element : queue)
{
System.out.println(queue.get(i).toString());
}

TYPO3 extbase: how to use ObjectStorage?

I'm trying to use a m:n relation, the same way as FrontEndUser is related to FrontEndUserGroup, e.g. without intermediate mm table. In my controller, I build my object, then I call $barRepository->update($barObject); to update the values of my object. However, it fails on the update function with the error:
Fatal error: Call to undefined method Cbrunet\Up\Domain\Model\Foo::getPosition() in /home/cbrunet/websites/typo3_src-6.1.1/typo3/sysext/extbase/Classes/Persistence/Generic/Backend.php on line 486
where Foo is the type of the object contained in the ObjectStorage of Bar. My understanding is that getPosition should be called on the ObjectStorage, not on the object contained into that ObjectStorage. However, I cannot figure out why this is not working in my case.
This is in TYPO3 6.1.5. Any hint would be appreciated.
The model of Bar which has a m:n relation to Foo looks like:
namespace Cbrunet\Up\Domain\Model;
class Bar extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
/**
* #var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\Cbrunet\Up\Domain\Model\Foo>
*/
protected $myprop;
public function __construct() {
$this->myprop = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
}
/**
* #param \TYPO3\CMS\Extbase\Persistence\ObjectStorage $myprop
* #return void
*/
public function setMyprop(\TYPO3\CMS\Extbase\Persistence\ObjectStorage $myprop) {
$this->myprop = $myprop;
}
/**
* #param \Cbrunet\Up\Domain\Model\Foo $myprop
* #return void
*/
public function addMyprop(\Cbrunet\Up\Domain\Model\Foo $myprop) {
$this->myprop->attach($myprop);
}
/**
* #param \Cbrunet\Up\Domain\Model\Foo $myprop
* #return void
*/
public function removeMyprop(\Cbrunet\Up\Domain\Model\Foo $myprop) {
$this->myprop->detach($myprop);
}
/**
* #return \TYPO3\CMS\Extbase\Persistence\ObjectStorage
*/
public function getMyprop() {
return $this->myprop;
}
}
The relevant code in my controller looks like:
/**
* action update
*
* #return void
*/
public function updateAction() {
$args = $this->request->getArgument('myargs');
foreach ($args as $k=>$val) {
$pp = $this->barRepository->findOneByAprop($k); // another prop of Bar, not illustrated in the code above.
$listepour = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
foreach ($val as $p) {
$ap = $this->fooRepository->findOneByUid(intval($p));
$listepour->attach($ap);
}
$pp->setMyprop($listepour);
$this->barRepository->update($pp); // error occurs here
}
$this->redirect('list');
}
Do you also have configured your TCA?
do you have an initStorageObjects-function in your domain model?
Also you can try to build these case with the extension-manager and compare the code.

NullPointerException when tyring to create table for mapped-superclass

I traced it down to the getDatastoreClass returning a null datastore class to the createPerImplementationColumnsForReferenceField.
I have tried both the 3.1.1 and now using 3.2.0-m4 release hoping that would fix my problem.
RDBMSStoreManager#getDatastoreClass(String className, ClassLoaderResolver clr);
It is returning a null datastore class to the
ReferenceMapping#createPerImplementationColumnsForReferenceField(boolean pk, boolean nullable, boolean serialised, boolean embedded, int fieldRole, ColumnMetaData[] columnMetaData, ClassLoaderResolver clr)
I am using the orm to annotate a mapped-superclass and this mapped-superclass does not have a table definition and both of my mapped-superclass throwing this exception.
499170 [http-bio-8080-exec-8] DEBUG DataNucleus.Datastore.Schema - Field [com.hp.vf.server.domain.AlertDefinition.isPublic] -> Column(s) ["ALERTDEFINITION"."ISPUBLIC"] using mapping of type "org.datanucleus.store.rdbms.mapping.java.BooleanMapping" (org.datanucleus.store.rdbms.mapping.datastore.SmallIntRDBMSMapping)
551964 [http-bio-8080-exec-8] DEBUG DataNucleus.Persistence - Managing Persistence of Class : com.hp.vf.analytics.shared.metric.Metric [Table : (none), InheritanceStrategy : subclass-table]
561964 [http-bio-8080-exec-8] ERROR DataNucleus.Datastore.Schema - An exception was thrown while adding/validating class(es) : null
java.lang.NullPointerException
at org.datanucleus.store.rdbms.mapping.java.ReferenceMapping.createPerImplementationColumnsForReferenceField(ReferenceMapping.java:452)
at org.datanucleus.store.rdbms.mapping.java.ReferenceMapping.prepareDatastoreMapping(ReferenceMapping.java:214)
at org.datanucleus.store.rdbms.mapping.java.ReferenceMapping.initialize(ReferenceMapping.java:110)
at org.datanucleus.store.rdbms.mapping.java.InterfaceMapping.initialize(InterfaceMapping.java:54)
In the Reference mapping, dc is null when trying to execute getIdMapping(), I have verified this in the debugger.
try
{
DatastoreClass dc = storeMgr.getDatastoreClass(implClass.getName(), clr);
m = dc.getIdMapping(); // DC is null
}
catch (NoTableManagedException ex)
{
// TODO Localise this message
throw new NucleusUserException("Cannot define columns for " + mmd.getFullFieldName() +
" due to " + ex.getMessage(), ex);
}
Here is the problematic class file.
public abstract class Metric implements IMetric {
/**
* Serialization ID
*/
private static final long serialVersionUID = 3806479436166940035L;
private Long id;
/**
* The name of the metric, this is not mandatory we have some metrics that
* may come back without names.
*/
protected String name;
/**
* This is an optional metric value that can be set by the script in order
* to add context to the execution of the metric.
*/
protected String context;
/**
* The list of violations associated with this metric.
*/
protected List<Violation> violations = null;
public Metric() {
violations = new ArrayList<Violation>();
}
/**
* Constructor that takes the name of the object and the value that it
* represents.
*
* #param name
* #param value
*/
public Metric(String name) {
this();
this.name = name;
}
/* (non-Javadoc)
* #see com.hp.vf.taskengine.shared.metric.IMetric#getName()
*/
#Override
public String getName() {
return name;
}
/* (non-Javadoc)
* #see com.hp.vf.taskengine.shared.metric.IMetric#setName(java.lang.String)
*/
#Override
public void setName(String name) {
this.name = name;
}
/**
* This is the context that represents the metric. This could have come from
* R and would be a Key:Value; pair of values used to calculate the value.
* For example if a metric was calculated for a product in houston for ISS
* the context may look like "ProdNum:1234;Factory:Houston;BUnit:ISS". This
* context is useful when chaining together tasks.
*
* #return String context used when chaining tasks together.
*/
public String getContext() {
return context;
}
/* (non-Javadoc)
* #see com.hp.vf.taskengine.shared.metric.IMetric#toString()
*/
public String toString() {
String debugString = "";
debugString += "Metric: " + name;
return debugString;
}
/* (non-Javadoc)
* #see com.hp.vf.taskengine.shared.metric.IMetric#hasMetricViolations()
*/
#Override
public boolean hasMetricViolations() {
return (violations != null && violations.size() > 0) ? true : false;
}
/* (non-Javadoc)
* #see com.hp.vf.taskengine.shared.metric.IMetric#getViolations()
*/
#Override
public List<IViolation> getViolations() {
return violations;
}
/* (non-Javadoc)
* #see com.hp.vf.taskengine.shared.metric.IMetric#setViolations(java.util.List)
*/
#Override
public void setViolations(List<IViolation> violations) {
this.violations = violations;
}
#Override
public Long getId() {
return id;
}
}
Here is an excert from my orm.xml file
<access>FIELD</access>
<mapped-superclass class="com.hp.vf.analytics.shared.metric.Metric" access="FIELD">
<attributes>
<basic name="name" />
<basic name="context" />
<one-to-many name="violations">
<cascade>
<cascade-all />
</cascade>
</one-to-many>
</attributes>
</mapped-superclass>
Am I doing something wrong or is this a bug?
I was able to resolve the problem using the tips from Datanucleus. I had multiple problems
Problems
The most obvious and silly on my part
If you have an one-to-many or one-to-one that uses an interface you must specify the target-entity.
/**
* The list of violations associated with this metric.
*/
protected List<IViolation> violations = null;
...
<one-to-many name="violations"
target-entity="com.vf.analytics.shared.metric.Violation">
<cascade>
<cascade-all />
</cascade>
</one-to-many>
Don't use generics, the jpa spec does not suppport them
Not sure if datanucleus supports generics but it but probably not recommended.
public MetricNumber< T extends Number> extends Metric implements IMetric {
T value;
}
If you extend an entity that is not annotated make sure that you add it to your orm.xml
I wasn't testing some of the objects so I assumed that datanucleus would ignore them but this appears not to be the case. I had extended third party classes that were not annotated but had not yet added them to the orm.xml, this was also causing null the null pointer exceptions I was getting.

Showing GWT validation errors using Editor Framework

I do GWT client side validation and I've a problem of how to show validation errors which are returned by validator. I debugged it and I can see that the set contains errors but driver doesn't show them. SimpleBeanEditorDriver is used.
Entry Entry = driver.flush();
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
Set<ConstraintViolation<Entry>> violations = validator.validate(Entry, Default.class);
if (violations.size() > 0) {
driver.setConstraintViolations(new ArrayList<ConstraintViolation<?>>(violations));
...
}
Tested on GWT ver. 2.4 and 2.5
The code is written according to https://developers.google.com/web-toolkit/doc/latest/DevGuideValidation but they're not using editors.
Does anybody make it work together GWT validation and Editors ? May be somebody can give links to good examples of it ? I couldn't find any working ones. Any help are welcomed!
Here is a simple example of how we are using editors/HasEditorError and ConstraintViolations. I have also included a sample from our ValueBoxEditorDecorator which allows us to layout error message.
Our activity
#Override
public void onSave() {
RequestFactoryEditorDriver<DashboardModelProxy, ?> driver = display.getDriver();
RequestContext context = driver.flush();
context.fire(new Receiver<Void>() {
#Override
public void onSuccess(Void response) {
Place previousPlace = clientFactory.getPlaceController().getPreviousPlace();
clientFactory.getPlaceController().goTo(previousPlace);
}
#Override
public void onFailure(ServerFailure error) {
display.showError(error.getMessage());
}
#Override
public void onConstraintViolation(Set<ConstraintViolation<?>> violations) {
display.getDriver().setConstraintViolations(violations);
}
});
}
Sample from our view.
/**
* Name component for the name of the analytics operation.
* This also implements {#link HasEditorErrors so it can show
* constraint violations when an error occurs.
*/
#UiField
ValueBoxEditorDecorator<String> name;
UIBinder example using the error location.
<t:ValueBoxEditorDecorator errorLocation="RIGHT" ui:field="name">
<t:valuebox>
<g:TextBox />
</t:valuebox>
</t:ValueBoxEditorDecorator>
The ValueBoxEditorDecorator we are using.
import java.util.List;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.editor.client.EditorError;
import com.google.gwt.editor.client.HasEditorErrors;
import com.google.gwt.editor.client.IsEditor;
import com.google.gwt.editor.client.adapters.TakesValueEditor;
import com.google.gwt.editor.ui.client.adapters.ValueBoxEditor;
import com.google.gwt.uibinder.client.UiChild;
import com.google.gwt.uibinder.client.UiConstructor;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.ValueBoxBase;
import com.google.gwt.user.client.ui.ValueListBox;
/**
* This is a copy of the original ValueBoxEditorDecorator in the gwt source The
* reason we are not using it is because it did not support laying out the error
* panel in a different location.
*
*
* A simple decorator to display leaf widgets with an error message.
* <p>
* <h3>Use in UiBinder Templates</h3>
* <p>
* The decorator may have exactly one ValueBoxBase added though an
* <code><e:valuebox></code> child tag.
* <p>
* For example:
*
* <pre>
* #UiField
* ValueBoxEditorDecorator<String> name;
* </pre>
*
* <pre>
* <e:ValueBoxEditorDecorator ui:field='name'>
* <e:valuebox>
* <g:TextBox />
* </e:valuebox>
* </e:ValueBoxEditorDecorator>
* </pre>
*
* #param <T>
* the type of data being edited
*/
public class ValueListBoxEditorDecorator<T> extends Composite implements HasEditorErrors<T>, IsEditor<TakesValueEditor<T>> {
/**
* The location of the text relative to the paging buttons.
*/
public static enum ErrorPanelLocation {
LEFT, RIGHT;
}
SimplePanel contents = new SimplePanel();
#Ignore
Label errorLabel = new Label();
HorizontalPanel layout = new HorizontalPanel();
private TakesValueEditor<T> editor;
/**
* Constructs a ValueBoxEditorDecorator.
*/
#UiConstructor
public ValueListBoxEditorDecorator(ErrorPanelLocation errorLocation) {
initWidget(layout);
setStyleName("gwt-ValueBoxEditorDecorator");
errorLabel.setStyleName("gwt-ValueBoxEditorDecorator-error");
errorLabel.getElement().getStyle().setDisplay(Display.NONE);
if (errorLocation == ErrorPanelLocation.RIGHT) {
layout.add(contents);
layout.add(errorLabel);
} else {
layout.add(errorLabel);
layout.add(contents);
}
}
/**
* Constructs a ValueBoxEditorDecorator using a {#link ValueBoxBase} widget
* and a {#link ValueBoxEditor} editor.
*
* #param widget
* the widget
* #param editor
* the editor
*/
public ValueListBoxEditorDecorator(ValueListBox<T> widget, TakesValueEditor<T> editor) {
this(ErrorPanelLocation.RIGHT);
contents.add(widget);
this.editor = editor;
}
/**
* Returns the associated {#link ValueBoxEditor}.
*
* #return a {#link ValueBoxEditor} instance
* #see #setEditor(ValueBoxEditor)
*/
public TakesValueEditor<T> asEditor() {
return editor;
}
/**
* Sets the associated {#link ValueBoxEditor}.
*
* #param editor
* a {#link ValueBoxEditor} instance
* #see #asEditor()
*/
public void setEditor(ValueBoxEditor<T> editor) {
this.editor = editor;
}
/**
* Set the widget that the EditorPanel will display. This method will
* automatically call {#link #setEditor}.
*
* #param widget
* a {#link ValueBoxBase} widget
*/
#UiChild(limit = 1, tagname = "valuebox")
public void setValueBox(ValueBoxBase<T> widget) {
contents.add(widget);
setEditor(widget.asEditor());
}
public void clearErrors() {
errorLabel.setText("");
errorLabel.getElement().getStyle().setDisplay(Display.NONE);
}
/**
* The default implementation will display, but not consume, received errors
* whose {#link EditorError#getEditor() getEditor()} method returns the
* Editor passed into {#link #setEditor}.
*
* #param errors
* a List of {#link EditorError} instances
*/
public void showErrors(List<EditorError> errors) {
StringBuilder sb = new StringBuilder();
for (EditorError error : errors) {
if (error.getEditor().equals(editor)) {
sb.append("\n").append(error.getMessage());
}
}
if (sb.length() == 0) {
clearErrors();
return;
}
errorLabel.setText(sb.substring(1));
errorLabel.getElement().getStyle().setDisplay(Display.INLINE_BLOCK);
}
}
This wiki might help you:
https://github.com/apetrelli/gwt-integration/wiki/GWT-Integration-Editor
although it integrates Editor, Validator and RequestFactory.
I created a Maven archetype that uses it:
https://github.com/apetrelli/samplegwt