jersey - using an object with a list of super Classes containing Objects of several sub classes - sub classes are not unmarshalled correctly - list

I have a QuestionsData class that has a List of QuestionData.
The QuestionData is an abstract class and has two implementations: TextQuestionData and SelectionQuestionData.
The problem is that after doing clientResponse.getEntity, I get the object with a list of SelectionQuestionData only, while I know that some of the questions are of type TextQuestionData.
I tried to add #XmlSeeAlso, but it did not help.
I also tried to change the order of elements in the #XmlElementRefs but that caused all the questions to be of type TextQuestionData.
I don't know if this is relevant or not, but the object I use in jersey is another Jaxb Object that has QuestionsData as a member
Here is the code:
#XmlRootElement(name = "questions")
#XmlAccessorType(XmlAccessType.FIELD)
#XmlSeeAlso({SelectionQuestionData.class, TextQuestionData.class })
public class QuestionsData {
#XmlElementRefs({#XmlElementRef(type = TextQuestionData.class), #XmlElementRef(type = SelectionQuestionData.class)})
private List<QuestionData> questions;
private QuestionsData() {}
public QuestionsData(List<QuestionData> questions) {
this.questions = questions;
}
}
#XmlRootElement(name = "question")
#XmlAccessorType(XmlAccessType.FIELD)
public class TextQuestionData extends QuestionData {
#XmlElement
private String someString;
public TextQuestionData() {}
}
#XmlRootElement(name = "question")
#XmlAccessorType(XmlAccessType.FIELD)
public class SelectionQuestionData extends QuestionData {
#XmlElements({#XmlElement(name = "option")})
private List<String> options;
public SelectionQuestionData() {}
}

In this use case the element name is used to determine which subclass (mapped with #XmlRootElement) should be instantiated during unmarshalling. Since you mapped both subclasses to question the JAXB (JSR-222) implementation can not determine the correct one to unmarshal. You will need to map them to different root elements.
TextQuestionData
#XmlRootElement(name = "textQuestion")
#XmlAccessorType(XmlAccessType.FIELD)
public class TextQuestionData extends QuestionData {
#XmlElement
private String someString;
public TextQuestionData() {}
}
SelectionQuestionData
#XmlRootElement(name = "selectionQuestion")
#XmlAccessorType(XmlAccessType.FIELD)
public class SelectionQuestionData extends QuestionData {
#XmlElements({#XmlElement(name = "option")})
private List<String> options;
public SelectionQuestionData() {}
}
For More Information
http://blog.bdoughan.com/2010/11/jaxb-and-inheritance-using-substitution.html

Related

Glass mapper does not load item childeren

We are facing issue in Glass mapper 4.0 where it does not load item children.
Here is our controller class , It is inheriting from GlassController:
public class CarouselController : GlassController
{
public ActionResult GetCarousel()
{
Model = this.GetDataSourceItem<CarouselViewModel>();
return View(Model);
}
}
And here is our View Model:
public class CarouselViewModel:Carousel_Folder
{
[SitecoreChildren]
public virtual IEnumerable<Carousel> Carousels { get; set; }
}
we get only the parent node information not the childeren (carousels) in the result
Here is the result we get:
[Result Image][1]
Also, following classes were generated with TDS:
[SitecoreType(TemplateId = ICarousel_FolderConstants.TemplateIdString )] //, Cachable = true
public partial interface ICarousel_Folder : IGlassBase
{}
Carousel template is inheriting from two templates content base and image base.
I had this issue before, for me i added [SitecoreChildren(IsLazy = false)] to my model and it works fine, in your case it should be like this :
public class CarouselViewModel:Carousel_Folder
{
[SitecoreChildren(IsLazy = false)]
public virtual IEnumerable<Carousel> Carousels { get; set; }
}
It seems that Carousels property is not par of the Carousel_Folder template, that's why your Interface/Class doesn't have something like:
[SitecoreType(TemplateId=ICarousel_FolderConstants.TemplateIdString)]
public partial class Carousel_Folder : GlassBase, ICarousel_Folder
{
[SitecoreField(ICarouselConstants.CarouselsFieldName)]
public virtual IEnumerable<Carousel> Carousels {get; set;}
}
In this case you will need to get the Parent item and get the children manually, i.e.:
var children = parentItem.Children.Select(x => x.GlassCast<Carousel>())

Extends Form Data in scout eclipse

I have some abstract form :
#FormData(value = AbstractMyFormData.class, sdkCommand = FormData.SdkCommand.CREATE)
public abstract class AbstractMyForm extends AbstractForm {
...
#Order(10.0)
#ClassId("MyForm.MyTable")
public class MyTable extends AbstractMyTableField {
...
}
}
This form data has some table (MyTable class as template) inside :
public abstract class AbstractMyFormData extends AbstractFormData {
private static final long serialVersionUID = 1L;
public AbstractMyFormData() {}
public MyTable getMyTable() {
return getFieldByClass(MyTable.class);
}
public static class MyTable extends AbstractMyTableData {
private static final long serialVersionUID = 1L;
public MyTable() {}
}
}
My real form extends AbstractMyForm :
#FormData(value = MyFormData.class, sdkCommand = FormData.SdkCommand.CREATE)
public class MyForm extends AbstractMyForm {
...
#Order(10.0)
#ClassId("MyForm.MyTable")
public class MyTable extends AbstractMyTableField {
...
}
}
form data for this is :
public class MyFormData extends AbstractMyFormData {
public MyTable getMyTable() {
return getFieldByClass(MyTable.class);
}
public static class MyTable extends AbstractMyTableData {
private static final long serialVersionUID = 1L;
public MyTable() {}
}
.....
.....
}
The problem is that both form datas (AbstractMyFormData and MyFormData) has implemented
public static class MyTable extends AbstractMyTableData
and than scout complains that has duplicate method getMyTable().
But I don't understand this. If MyFormData is extend from AbstractMyFormData than MyFormData must not have this method inside because it already has it his parent.
How to do this? I see FormData.SdkCommand.USE that by description might be it, but I don't now how to use it.
Second question witch might be related is how to inject table in AbstractMyForm like normal AbstractForm inject Cancel button?
EDIT :
Code for classes :
ABSTRACT FORM
#FormData(value = AbstractPurchasePriceFormData.class, sdkCommand = FormData.SdkCommand.CREATE)
#ClassId("41f0f405-b257-47e7-accf-270f5be158ce")
public abstract class AbstractMyForm extends AbstractForm {
/**
* #throws org.eclipse.scout.commons.exception.ProcessingException
*/
public AbstractMyForm() throws ProcessingException {
super();
}
#Order(10.0)
public class MainBox extends AbstractGroupBox {
#Order(10.0)
public class MyTable extends AbstractMyTableField {
}
}
#Override
protected String getConfiguredTitle() {
return TEXTS.get("AbstractMyForm");
}
}
AbstractMyTableField template :
import org.eclipse.scout.commons.annotations.FormData;
import org.eclipse.scout.commons.annotations.Order;
import org.eclipse.scout.rt.client.ui.basic.table.columns.AbstractIntegerColumn;
import org.eclipse.scout.rt.client.ui.basic.table.columns.AbstractStringColumn;
import org.eclipse.scout.rt.client.ui.form.fields.tablefield.AbstractTableField;
import org.eclipse.scout.rt.extension.client.ui.basic.table.AbstractExtensibleTable;
#FormData(value = AbstractMyTableFieldData.class, sdkCommand = FormData.SdkCommand.CREATE, defaultSubtypeSdkCommand = FormData.DefaultSubtypeSdkCommand.CREATE)
public abstract class AbstractMyTableField extends AbstractTableField<AbstractMyTableField.Table> {
#Order(10.0)
public class Table extends AbstractExtensibleTable {
#Order(10.0)
public class NameColumn extends AbstractStringColumn {
}
#Order(20.0)
public class AgeColumn extends AbstractIntegerColumn {
}
}
}
FOR REAL FORM you just create form from template :
and in main box add MyTable like :
insted :
#Order(10.0)
public class MainBox extends AbstractGroupBox {
}
do :
#Order(10.0)
public class MainBox extends AbstractGroupBox {
#Order(10.0)
public class MyTable extends AbstractMyTableField {
}
}
I hope I was more explicit this time.
EDIT 2
I admit that creating main box inside abstract form is maybe not the right approach, but what I want to achive is to have AbstractMyTableField in AbstractMyFormData, so I can rely on server side that all forms that extend from AbstractMyForm has this in form data so I can write only one server method for all forms (returning AbstractMyFormData).
FormData and Form hierarchy
The formData hierarchy reflects the form hierarchy. If you form hierarchy looks like this:
MyForm
|-- PersonForm
| \-- VipForm.
\-- CompanyForm
Your formData hierarchy looks like this:
MyFormData
|-- PersonFormData
| \-- VipFormData
\-- CompanyFormData
Do not define the MainBox twice
With you example, You have absolutely right the code generated by the SDK contains compilation errors.
I have tried to explain it in your question about form template, but it doesn’t make any sense to have a main box in the form template and in one in the concrete form.
Each form contains:
0..n variables
0..n Key Strokes (inner classes implementing IKeyStroke)
exactly 1 Main Box (inner class implementing IGroupBox)
0..n ToolButtons (inner classes implementing IToolButton)
1..n Form Handler (usually defined as inner classes implementing IFormHandler, but since the handler is set as parameter of AbstractForm.startInternal(IFormHandler) the handler can be defined everywhere)
In your case, when you consider how the concrete form (MyForm) looks like, you notice that it have two MainBox:
one corresponding to ConcreteForm.MainBox
one contributed by the abstract class and corresponding to AbstractMyForm.MainBox
I would have expected a compile error (from a pure jave point of view) but it seems to work.
At runtime scout pick one of the two MainBox classes and use it as root of the field tree. I am not even sure if the selected MainBox is well defined by scout or if you just randomly get one of the two (depending on what the java introspection Class.getClasses() will return).
I do not see what is ensured with the pattern you have used. You can define something else in the main box of the concrete form:
#Order(10.0)
public class MainBox extends AbstractGroupBox {
#Order(10.0)
public class NameField extends AbstractStringField {
#Override
protected String getConfiguredLabel() {
return TEXTS.get("Name");
}
}
#Order(20.0)
public class OkButton extends AbstractOkButton {
}
#Order(30.0)
public class CancelButton extends AbstractCancelButton {
}
}
In this case I do not have any table extending AbstractMyTableField in the concrete form, even if one table is defined in the abstract class used as form template.
#FormData configuration
You can influence the generation of the formData with the formData annotation. Here two examples:
1/ If you work with group boxes defined as templates you can decide if the GroupBoxData should be an external class or not. You can try it by ourself:
Check or uncheck the checkbox "Create external FormData". You can compare the output (generated classes) and the #FormData annotation.
2/ For TableData you can decided how the structure in the formData will look like (bean based or array based). See TableData on the eclipse wiki
Usage of the different options is described in the JavaDoc of the #FormData annotation.
If you have moved some field from one class to another, I recommend you to regenerate all the FormDatas with the SDK. (“Update all formData classes” in the scout explorer). This might solve your compilations problem.

Rest Web Service using Interfaces

I am trying to create a REST web-service in Java using RestEasy with the design similar to the example classes that I have shown below:
#Path("/rest")
public class TestRestService {
#GET
#Path("/test")
#Produces("application/xml")
public Response sayTestXml() {
return getImplementation();
}
public Response getImplementation() {
IInterface refToImpl = TestService.getImplementation();
return Response.status(Status.OK).entity(refToImpl).build();
}
}
public class TestService {
public static IInterface getImplementation() {
IInterface ref = new Implementation();
return ref;
}
}
public interface IInterface {
public long getLong();
public String getString();
public boolean getBoolean();
public List<IRelatedInterface> getRelations();
}
public interface IRelatedInterface {
public float getFloat();
public char getChar();
public byte getByte();
}
#XmlRootElement(name="interface")
#XmlAccessorType(XmlAccessType.PROPERTY)
public class Implementation implements IInterface {
#XmlElement(name="tlong", required=true)
public long getLong() {
return 42;
}
#XmlElement(name="tstring", required=true)
public String getString() {
return "test";
}
#XmlElement(name="tboolean", required=true)
public boolean getBoolean() {
return false;
}
#XmlElementWrapper(name = "relations")
#XmlElement(name = "relation", required=false)
public List<IRelatedInterface> getRelations() {
List<IRelatedInterface> list = new ArrayList<IRelatedInterface>();
RelatedImplementation impl = new RelatedImplementation();
list.add(impl);
return list;
}
}
#XmlRootElement(name="relatedInterface")
#XmlAccessorType(XmlAccessType.PROPERTY)
public class RelatedImplementation implements IRelatedInterface {
#XmlElement(name="tfloat", required=true)
public float getFloat() {
return 1.23f;
}
#XmlElement(name="tchar", required=true)
public char getChar() {
return 'A';
}
#XmlElement(name="tbyte", required=true)
public byte getByte() {
return 'Z';
}
}
So, when I try this design then JAXB complains as below:
com.sun.xml.bind.v2.runtime.IllegalAnnotationsException:
2 counts of IllegalAnnotationExceptions com.intuit.whitespace.IRelatedInterface is an interface, and JAXB can't handle interfaces.
this problem is related to the following location: at com.intuit.whitespace.IRelatedInterface at public java.util.List com.intuit.whitespace.Implementation.getRelations() at com.intuit.whitespace.Implementation com.intuit.whitespace.IRelatedInterface does not have a no-arg default constructor. this problem is related to the following location: at com.intuit.whitespace.IRelatedInterface at public java.util.List com.intuit.whitespace.Implementation.getRelations() at com.intuit.whitespace.Implementation
My question is, is there a way to solve this? I have tried some things but none of them have worked. I am considering Spring OXM or a MessageBodyWriter based solution, but I wanted to ask if there were any other suggestions that would help me better?
Okay, I solved it by making the following changes:
Used the type attribute in #XmlElement
public class Implementation implements IInterface {
#XmlElementWrapper(name = "relations")
#XmlElement(name = "relation", required=false, type=RelatedImplementation.class)
public List<IRelatedInterface> getRelations() {
....
}
}
That is all!

How to avoid casting between the DL - BL - UI layers ? (C#)

I designing an applications which basically has 3 different logic layers:
DB connector (implemented by ADO.NET).
BL the business logic (the only thing the UI knows).
DB repositories (connects between the first two).
The DB repositories are separated into sections of dependency and every final entity is polymorphic to one interface. In some cases there are dependencies between objects inside the same dependency sections - ISectionFactory (hence dependent).
In practice the BL is going to ask for an object of specific type (such as IngrediantType in my example) from the MainFactory (which is a factor for all the DB)
Because of this design I am forced to cast types on the UI - which obviously is a drag.
How can I change the design ?
Here is a brief look of design:
public class MainFactory
{
private Dictionary<Type, ISectionFactory> m_SectionsFactories;
private ISectionFactory treatmentsSectionFactory =
new TreatmentsSectionFactory();
public MainFactory()
{
m_SectionsFactories = new Dictionary<Type, ISectionFactory>
{
{typeof(IngrediantType),treatmentsSectionFactory}
};
}
public IConcreteDataCollection GetConcreteData(Type i_EntitiesName)
{
return m_SectionsFactories[i_EntitiesName]
.GetConcreteData(i_EntitiesName);
}
}
internal interface ISectionFactory
{
IConcreteDataCollection GetConcreteData(Type i_EntitiesName);
}
public class TreatmentsSectionFactory : ISectionFactory
{
private Dictionary<Type, IConcreteDataCollection>
m_ConcreteDataCollections;
private IngrediantTypes m_IngrediantTypes = new IngrediantTypes();
private Ingrediants m_Ingrediants = new Ingrediants();
public TreatmentsSectionFactory()
{
m_ConcreteDataCollections =
new Dictionary<Type, IConcreteDataCollection>();
m_ConcreteDataCollections
.Add(typeof(IngrediantType), m_IngrediantTypes);
m_ConcreteDataCollections
.Add(typeof(Ingrediants), m_Ingrediants);
}
public IConcreteDataCollection GetConcreteData(Type i_EntitiesName)
{
return m_ConcreteDataCollections[i_EntitiesName];
}
}
public interface IConcreteDataCollection : IEnumerable
{
// Iteratable.
IConcreteData GetById(int i_Id);
void AddNewConcreteData(IConcreteData i_ConcreteData);
void UppdateConcreteData(IConcreteData i_ConcreteData);
void DeleteConcreteData(IConcreteData i_ConcreteToDelete);
}
public class IngrediantTypes : IConcreteDataCollection
{
public string TestType { get; set; }
public IConcreteData GetById(int i_Id){}
public void AddNewConcreteData(IConcreteData i_ConcreteData){}
public void UppdateConcreteData(IConcreteData i_ConcreteData){}
public void DeleteConcreteData(IConcreteData i_ConcreteToDelete){}
public IEnumerator GetEnumerator(){}
}
// also implements IConcreteDataCollection
public class Ingrediants : IConcreteDataCollection
{
}
public interface IConcreteData
{
public int Index { set; get; }
} // the final (highest) entity of all DB entities
public class IngrediantType : IConcreteData
{
public int Index { set; get; }
// other set of properties
}
public class Ingrediant : IConcreteData
{
public int Index { set; get; }
public IngrediantType RelatedIngrediantType { set; get; }
// other set of properties
}
public class mainClass
{
public static void main()
{
MainFactory factory = new MainFactory();
var type = typeof(IngrediantType);
// returns a IngrdiantTypes of type (IConcreteDataCollection)
var t = factory.GetConcreteData(typeof(IngrediantType));
// I want to use the IngrediantType without casting !!!
var s = t.GetById(2);
}
}
It's a little hard to tell what's going on here, but I think the key will be to take advantage of generics like so:
public IConcreteDataCollection<T> GetConcreteData<T>()
{
return ...;
}
If I understand your question correctly, this will allow you to say:
var t = factory.GetConcreteData<IngrediantType>();
You will need to change almost every class in your code to use generics.

How to verify that method argument's property values are set when mocking methods with Moq?

Not sure if it has been asked before, here is the question.
Code first:
public class Customer {
public string Password { get; set; }
public string PasswordHash { get; set; }
}
public class CustomerService {
private ICustomerRepository _repo;
public CustomerService(ICustomerRepository repo) {
_repo = repo;
}
public int? AddCustomer(Customer customer) {
customer.PasswordHash = SHA1Hasher.ComputeHash(customer.Password);
return _repo.Add(customer);
}
}
public interface ICustomerRepository {
int? Add(Customer c);
}
public class CustomerRepository : ICustomerRepository {
int? AddCustomer(Customer customer) {
// call db and return identity
return 1;
}
}
[TestClass]
public class CustomerServiceTest {
[TestMethod]
public void Add_Should_Compute_Password_Hash_Before_Saving() {
var repoMock = new Mock<ICustomerRepository>();
//how do I make sure the password hash was calculated before passing the customer to repository???
}
}
How do I verify that CustomerService assigned the PasswordHash before passing the customer to repository?
There are several approaches you could take. Although not necessarily the best solution, here's one that doesn't require you to change your existing API. It assumes that SHA1Hasher.ComputeHash is a public method.
[TestClass]
public class CustomerServiceTest
{
[TestMethod]
public void Add_Should_Compute_Password_Hash_Before_Saving()
{
var customer = new Customer { Password = "Foo" };
var expectedHash = SHA1Hasher.ComputeHash(customer.Password);
var repoMock = new Mock<ICustomerRepository>();
repoMock
.Setup(r => r.Add(It.Is<Customer>(c => c.PasswordHash == expectedHash)))
.Returns(1)
.Verifiable();
// invoke service with customer and repoMock.Object here...
repoMock.Verify();
}
}
A slightly better solution would be to turn the SHA1Hasher into an injected service (such as IHasher) so that you can confirm that the PasswordHash property was assigned the value created by the IHasher instance.
Opening op your API even more, you could make the PasswordHash property virtual, so that you could pass a Mock Customer to the AddCustomer method to verify that the property was correctly set.
You could make SHA1Hasher non-static and virtual or wrap it in a ISHA1Hasher interface which can then be mocked. Wrapping static methods and objects in mockable classes is a classic way to increase testability.