Hi Dan,

> You haven't said, exactly, what your problem is... ?;

The problem that we have is that we need to show an objecto ValueObject as
a property of an entity and the wicket is no being able to explore it.
In this case, ContactVO have 3 attributes with a String type: Telephone,
Adress, email.


While we were  trying  to work we the solution you gave us I got stuck with
this error:

@Override
    public ApplicationAdvice appliesTo(final IModel<?> model) {
     if (!(model instanceof ScalarModel)) {
            return ApplicationAdvice.DOES_NOT_APPLY;
        }

     final ScalarModel scalarModel = (ScalarModel) model;
        scalarModel.getTypeOfSpecification().
     return
appliesIf(ContactoVO.class.isAssignableFrom(scalarModel.getTypeOfSpecification().getUnderlyingClass());
    }

the method getUnderlyingClass() is not part of  getTypeOfSpecification()


I was searching in the web and it seems to be a method of this class:
com.google.api.client.util.ClassInfo;

But I still can't work on it by the way you suggest...
Hope you can help us to close this implementation.

Regards



2013/10/2 Dan Haywood <[email protected]>

> within...
>
>
> On 2 October 2013 03:45, Ezequiel Celiz <[email protected]> wrote:
>
> >
> > [snip] I would like you to take a look to the
> > things that we tried to do to show the object ContactVO with wicket
> viewer.
> >
> > We based on the structure of the component BookmarkedPages [snip]
> >
> > we create this files in this location webapp/src/main/java/app
> >
> > * ContactVOPagePanelFactoryRegistrar.java
> > * ContactVOPagePanelFactory.java
> > * ContactVOPagePanel.java
> > * ContactVOPagePanel.html
> >
> >
> That looks good so far.
>
>
>
>
>
> > Below I'll write you each class in detail:
> >
> > ////////////////////////////////////////////////////
> > //////ContactoVOPagePanelFactoryRegistrar///////////
> > ////////////////////////////////////////////////////
> > @Singleton
> > public class ContactoVOPagePanelFactoryRegistrar extends
> > ComponentFactoryRegistrarDefault {
> > @Override
> > public void addComponentFactories(ComponentFactoryList
> componentFactories)
> > {
> >     componentFactories.add(new ContactVOPagePanelFactory());
> >     super.addComponentFactories(componentFactories);
> >     }
> > }
> >
> >
> That looks ok.  You possibly want to rename the class to
> "MyAppComponentFactoryRegistrarDefault" because if there were any other
> customisations, they would also be registered here.
>
>
>
> [1]
>
> http://isis.apache.org/components/viewers/wicket/customizing-the-viewer.html
>
>
>
> > In the class QuickstartApplication.java we make use of this method:
> >
> >
> >
> bind(ComponentFactoryRegistrar.class).to(ContactVOPagePanelFactoryRegistrar.class);
> >
> >
> Yup; that's correct.
>
> As an alternative to creating your own custom ComponentFactoryRegistrar,
> you can also register component factories by adding some some metadata in
> META-INF/services; Isis can then (using the ServiceLoader API)
> automatically discover the component just by it being on the classpath.
>  There's some detail about this on [1] (search for the "Additional Views of
> Collections" section).
>
>
>
>
> > ////////////////////////////////////////////////////
> > ///////////ContactVOPagePanelFactory///////////////
> > ////////////////////////////////////////////////////
> >
> > public class ContactVOPagePanelFactory extends ComponentFactoryAbstract {
> >
> >     private static final long serialVersionUID = 1L;
> >
> >     public ContactVOPagePanelFactory() {
> >         super(ComponentType.VALUE);
> >     }
> >
> >     @Override
> >     public ApplicationAdvice appliesTo(final IModel<?> model) {
> >         return appliesIf(model instanceof ValueModel);
> >     }
> >
> >     @Override
> >     public Component createComponent(final String id, final IModel<?>
> > model) {
> >         final ValueModel valueModel = (ValueModel) model;
> >         return new ContactVOPagePanel(id, valueModel);
> >     }
> >
> > }
> >
> >
> Um, I'm not sure what sort of model the ContactVO would get created within.
>  I have a feeling it might be in a ScalarModel rather than a ValueModel.
>
> If that's the case, then your appliesTo method would need to look similar
> to that of ValuePanelFactory.  However, you should also filter to make sure
> that the "payload" of the ScalarModel is of the right type, ie an
> instanceof ContactVO.
>
>     @Override
>     public ApplicationAdvice appliesTo(final IModel<?> model) {
>         if (!(model instanceof ScalarModel)) {
>             return ApplicationAdvice.DOES_NOT_APPLY;
>         }
>         final ScalarModel scalarModel = (ScalarModel) model;
>         return
>
> appliesIf(ContactVO.class.isAssignableFrom(scalarModel.getTypeOfSpecification().getUnderlyingClass());
>     }
>
>
> But I might be wrong about this; it is possible that your ContactVO is
> wrapped up in a ValueModel?  In which case the code would still need to
> check the type of the object held within the (value) model.
>
>
>
>
> > We believe that the ComponentType that may help us to resolve our problem
> > is ComponentType.VALUE
> >
> >
> You haven't said, exactly, what your problem is... ?
>
>
>
> > ////////////////////////////////////////////////////
> > //////////////////ContactVOPagePanel///////////////
> > ////////////////////////////////////////////////////
> >
> > public class ContactVOPagePanel extends PanelAbstract<ValueModel> {
> >
> > private static final String ID_ADDRESS = "address";
> > private static final String ID_TELEPHONE = "telephone";
> > private static final String ID_EMAIL = "email";
> >  private static final long serialVersionUID = 1L;
> >  public ContactVOPagePanel(String id, ValueModel model) {
> > super(id, model);
> > buildGui();
> > }
> >
> > private void buildGui() {
> >  //final ValueModel contactVOPagePanel = getModel();
> >  final Label address = new Label(ID_ADDRESS,"address of entity");
> >
> > final Label telephone = new Label(ID_TELEPHONE,"telephone of entity);
> >
> > final Label email = new
> Label(ID_EMAIL,getModel().getObject().toString());
> >  add(address);
> > add(telephone);
> > add(email);
> >  }
> > }
> >
> >
>
> That creates labels, but I suspect you will want to render label/forms.
>  The EntityPropertiesForm#addPropertyInColumn(...) method shows how I use
> the:
>
> getComponentFactoryRegistry().addOrReplaceComponent(container, ID_PROPERTY,
> ComponentType.SCALAR_NAME_AND_VALUE, scalarModel);
>
> to create a component to add for each name/value of an entity.  I think you
> might want to do something similar.
>
>
>
>
> > ////////////////////////////////////////////////////
> > /////////////ContactoVOPagePanel.html///////////////
> > ////////////////////////////////////////////////////
> >
> > <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "
> > http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd";>
> > <html xmlns="http://www.w3.org/1999/xhtml";
> >       xmlns:wicket="
> > http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd";
> >       xml:lang="en"
> >       lang="en">
> > <body>
> > <div>
> > <table border="0">
> > <tr>
> > <td>
> > ADDRESS:
> > </td>
> > <td>
> > <span wicket:id="address"></span>
> > </td>
> > </tr>
> > <tr>
> > <td>
> > TELEPHONE:
> > </td>
> > <td>
> > <span wicket:id="telephone"></span>
> > </td>
> > </tr>
> > <tr>
> > <td>
> > EMAIL:
> > </td>
> > <td>
> > <span wicket:id="email"></span>
> > </td>
> > </tr>
> > </table>
> > </div>
> > </body>
> > </html>
> >
> >
>
> In which case, the code here would be similar to the markup in
> EntityPropertiesForm.html:
>
>                  <div class="inputFormTable properties">
>                      <fieldset wicket:id="memberGroup" class="memberGroup
> myBlockContainer">
>                      <legend wicket:id="memberGroupName">[group
> name]</legend>
>                  <div wicket:id="properties">
>                           <div wicket:id="property"
> class="property">[property]</div>
>                  </div>
>                  </fieldset>
>                  </div>
>
>
>
>
> > Well, now some questions:
> >
> > 1) Are we taking the rigth way to succed in our goal?
> >
> >
> Definitely "on the way".
>
>
>
> > 2)If an entity needs to use a valueObject Contact, we should add the
> > property: private ContactVO contactVO;
> > What do we have to do to make the framework realizes that object type
> must
> > use the component previously registered?
> >
> >
> This is the appliesTo method.  I suggest you put a conditional break point
> in one of the existing component factories (eg ValuePanelFactory,
> StandaloneValuePanelFactory) to see what model the framework gives you.
>
>
>
>
> > 3)While drawing the Panel, how do we get the information of the object
> > contactVO in order to be able of upload them in the corresponding Label?
> Is
> > this posible by using ObjectAdapter with getModel().getObject()?
> >
> >
> Yep, the contactVO pojo will be wrapped in an ObjectAdapter, from whence
> you can get to the rest of the Isis metamodel (ObjectSpecification).
>  ObjectAdapter corresponds to java.lang.Object, ObjectSpecification
> corresponds to java.lang.Class.
>
>
>
>
> > Sorry for the extended mail,
> >
>
> No worries.  As I was writing this reply, I was wondering myself how
> feasible this is.  It is possible that you might hit a showstopper
> somewhere, or I might need to dig into things a little myself.  If you want
> to create a sample application up on github, then we could work on it
> together.
>
> Cheers
> Dan
>
>
>
>
> > regards!
> >
> >
> > 2013/9/18 Luis Parada <[email protected]>
> >
> > > Thank you Dan, we are going to work with the wicket viewer, so I will
> let
> > > you know later if we get something. Best Regards.-
> > >
> > >
> > > 2013/9/18 Dan Haywood <[email protected]>
> > >
> > > > Hi Luis,
> > > > welcome to the Isis mailing list.
> > > >
> > > > But my apols to you and Ezequiel, I somehow dropped the ball and
> missed
> > > > this question.
> > > >
> > > > To answer some of your question: to get the ContactVO to persist - as
> > you
> > > > have done - it is sufficient only to make it serializable.  However,
> if
> > > you
> > > > want it to be stored as something other than a blob, you'll need to
> use
> > > the
> > > > JDO APIs (eg as is done for Joda types).
> > > >
> > > > Your issue, though, is on the UI side.  And, unfortunately, right now
> > > Isis
> > > > doesn't provide an out-of-the-box capability to render composite
> value
> > > > objects such as you have defined here.  It most certainly ought to do
> > so,
> > > > and indeed we have a ticket for something very similar... [1] it just
> > > isn't
> > > > implemented, I'm afraid.
> > > >
> > > > The EncoderDecoder stuff won't help... that is used by some of the
> > other
> > > > object stores (eg XML, NoSQL).  But it's irrelevant for Wicket/JDO.
> > > >
> > > > The main issue is that the Wicket viewer doesn't "look inside" the
> > > > structure of your ContactVO in order to build up a suitable UI.  For
> > > > example, the ContactVO is basically 3 string properties, and you
> would
> > > > presumably want 3 fields.  It's just not smart enough to do that.
> > > >
> > > > I can offer a possible workaround for you, if you want, which *might*
> > > work.
> > > >  The Wicket viewer *is* extensible, and so you could define and
> > register
> > > > your own ContactVOComponentFactory and have it build up a custom
> > > > ContactVOComponent (a panel) for rendering the parts of the contact
> as
> > > > individual fields.
> > > >
> > > > Have a look at ComponentFactoryRegistryDefault and how some of the
> > other
> > > > ComponentFactorys work - it's basically the chain of responsibility
> > > > pattern.
> > > >
> > > > Or... alternatively you might want to generalize this, in other words
> > > > implement [1].  Note that [1] uses the AggregatedFacet as the
> indicator
> > > on
> > > > the referenced object that it should be displayed "inline".  If this
> > > > reference is mapped using JDO's @Embedded, it would also save you the
> > > > hassle of doing extra JDO datatype mappings.
> > > >
> > > > HTH, come back to me if none of the above makes sense...
> > > >
> > > > Best
> > > > Dan
> > > >
> > > >
> > > > [1] https://issues.apache.org/jira/browse/ISIS-348
> > > >
> > > >
> > > >
> > > >
> > > >
> > > >
> > > >
> > > > On 18 September 2013 13:26, Luis Parada <[email protected]>
> > > > wrote:
> > > >
> > > > > Hi, I´m working on this with Ezequiel and we could persist the
> > Contact
> > > > VO.
> > > > > The problem is that we can not show the object in the viewer
> because
> > > the
> > > > > object is serialized. We found
> > > > > the public interface EncoderDecoder<T> {} wich implements this
> > method:
> > > T
> > > > > fromEncodedString(String encodedString); so we appreciate any help
> > > > > explaining us how to use it.
> > > > >
> > > > > At this moment we have overrided the methods: protected String
> > > > > doEncode(final Object object) and protected Contact doRestore(final
> > > > String
> > > > > data) of ContactoValueSemanticsProvider but is not working yet.
> > > > >
> > > > > protected String doEncode(final Object object) {
> > > > > final Contacto contacto = (Contacto) object;
> > > > > final String valor = String.valueOf(contacto.getDomicilio() + "-" +
> > > > > contacto.getEmail() + "-" + contacto.getTelefono());
> > > > > return valor;
> > > > > }
> > > > >
> > > > > protected Contacto doRestore(final String data) {
> > > > > final String[] partes = data.split("-");
> > > > > final String domicilio = partes[0];
> > > > > final String correo = partes[1];
> > > > > final String telefono = partes[2];
> > > > > return new Contacto(domicilio, correo, telefono);
> > > > > }
> > > > > Thank´s.
> > > > >
> > > > >
> > > > > 2013/9/12 Ezequiel Celiz <[email protected]>
> > > > >
> > > > > > Hi community
> > > > > >
> > > > > > I'm trying to implement the annotation @Value in my application
> to
> > > use
> > > > > the
> > > > > > "Value Objects" as defined in the concept of DDD .
> > > > > >
> > > > > > I had no success : How I can set my class as a genuine Custom
> Value
> > > > Type?
> > > > > > so that it can be used in the entities that require it.
> > > > > >
> > > > > > I want to create the classic VO : "Contact" which consists of the
> > > > > following
> > > > > > properties ( in my case) :
> > > > > >
> > > > > > Address, Telephone and Email.
> > > > > >
> > > > > >     @Value ( semanticsProviderName = "
> > > > > >  ContactValueSemanticsProvider.class " )
> > > > > >     public class Contact  {
> > > > > >
> > > > > >     / *
> > > > > >     / Need to the builder?
> > > > > >     /
> > > > > >     / Public Contact ( String a, String t , String e) {
> > > > > >     / This.address = a;
> > > > > >     / This.telephone = t;
> > > > > >     / This.email = e ;
> > > > > >     / }
> > > > > >     /
> > > > > >     / *
> > > > > >
> > > > > >     private String address ;
> > > > > >
> > > > > >     public String getAddress ( ) {
> > > > > >         return address ;
> > > > > >     }
> > > > > >
> > > > > >     public void setAddress (String address) {
> > > > > >         this.address = address ;
> > > > > >     }
> > > > > >
> > > > > >     private String telephone ;
> > > > > >
> > > > > >     getTelephone public String ( ) {
> > > > > >         return telephone ;
> > > > > >     }
> > > > > >
> > > > > >     public void setTelephone (String telephone) {
> > > > > >         this.telephone = telephone ;
> > > > > >     }
> > > > > >
> > > > > >     private String email ;
> > > > > >
> > > > > >     getEmail public String ( ) {
> > > > > >         return email ;
> > > > > >     }
> > > > > >
> > > > > >     public void setEmail (String email ) {
> > > > > >         this.email = email ;
> > > > > >     }
> > > > > >
> > > > > >  }
> > > > > >
> > > > > > where ContactValueSemanticsProvider.class :
> > > > > > public final class ContactValueSemanticsProvider
> > > > > > extends AbstractValueSemanticsProvider <Conctact> {}
> > > > > >
> > > > > > Then I wonder if the entity would have to have an attribute :
> > > > > >
> > > > > >     private Contact contact ;
> > > > > >
> > > > > >     public GetContact ( ) {
> > > > > >         return contact ;
> > > > > >     }
> > > > > >
> > > > > > Finally in the service when I creating the entity object :
> > > > > >
> > > > > >    SomeEntity public newEntity (
> > > > > >             @ Optional
> > > > > >             @ Named ( " Address" ) String address,
> > > > > >             @ Optional
> > > > > >             @ Named ( " Telephone" ) String telephone ,
> > > > > >             @ Optional
> > > > > >             @ Named ( " email " ) String email
> > > > > >             ) {
> > > > > >
> > > > > >    final Contact contact
> > > > > >
> > > > > >             / / The correct way to instantiate is THROUGH
> > > > > > newTransientInstance ( Contact.class ) ?
> > > > > >
> > > > > >             pourContacter (contact) ;
> > > > > >
> > > > > >  @ Hidden
> > > > > >  SomeEntity public pourContacter ( ) (
> > > > > >             Final Contact Contact
> > > > > >         ) {
> > > > > >         SomeEntity end someEntity = newTransientInstance (
> > > > > SomeEntity.class
> > > > > > ) ;
> > > > > >         someEntitity.setContact (contact) ;
> > > > > >         persistIfNotAlready ( someEntity ) ;
> > > > > >
> > > > > >         someEntity return ;
> > > > > >     }
> > > > > >
> > > > > > It is the right way? or the way to work with the Value Object in
> > ISIS
> > > > is
> > > > > > another?
> > > > > >
> > > > > > I welcome your suggestions
> > > > > > Thank you very much as always for your attention
> > > > > > Cheers !
> > > > > > Ezequiel
> > > > > >
> > > > >
> > > >
> > >
> >
>

Reply via email to