ComboBox and original value as an array - vaadin

I have a legacy MongoDB database (collection) where there is single value stored as an array List . But its only a one value that must be, in UI selected with ComboBox. So I have a model bean
class Project {
List<Company> companies;
}
And I would like to bind it and edit with VAADIN ComboBox. Initialy I thought I can use some customer converter for ComboBox but can't get it to work. Combo should edit the first value in the List (Company bean) and store back into companies field as an array to remain compatible. Is it event possible to do it and if so can you give me some hint how to accomplish this?
EDIT: Enhanced explanation
MongoDB model:
class Project {
List<Company> companies;
}
Vaadin UI:
ComboBox companies;
... 'companies' ComboBox is attached to BeanItemContainer which is List ... selection is therefore the only one Company bean, but should be stored, for compatibility reasons, as List with only one item. So basicly ComboBox should be able to read existing List value as single Company, allow selection and store it as List with this one selecten Company.

After the last question update the answer below may not be correct. Waiting for OP to provide details so the answer can be corrected.
You can use a sort of a delegation approach using a ProjectDelegator wrapper. This will allow you to bind the form to the Project name (using the project field) as well as the Company name (using the getCompany() getter)
1. The UI class
#PreserveOnRefresh
#SpringUI
public class MyVaadinUI extends UI {
#Override
protected void init(VaadinRequest request) {
final VerticalLayout layout = new VerticalLayout();
layout.setMargin(true);
setContent(layout);
// add the form to the UI
layout.addComponent(new MyForm(new ProjectDelegator(new Project("myProject", new Company("myCompany")))));
}
}
2. The form
// "wrapping" the form in a custom component. not really needed but a nice touch
public class MyForm extends CustomComponent {
public MyForm(ProjectDelegator projectDelegator) {
FormLayout layout = new FormLayout();
// use a binder to create fields and bind the members using reflection
BeanFieldGroup<ProjectDelegator> binder = new BeanFieldGroup<>(ProjectDelegator.class);
// bind the project name using the "project" field
layout.addComponent(binder.buildAndBind("Project", "project.name"));
// bind the company name using the "getCompany" method
layout.addComponent(binder.buildAndBind("Company", "company.name"));
// add a "save" button
layout.addComponent(new Button("Save", new Button.ClickListener() {
#Override
public void buttonClick(Button.ClickEvent clickEvent) {
try {
// commit changes
binder.commit();
} catch (FieldGroup.CommitException e) {
// didn't expect this! what gives?!
System.out.println("Could not save data: [" + e.getMessage() + "]");
}
}
}));
// set the delegator as the binder data source
binder.setItemDataSource(projectDelegator);
setCompositionRoot(layout);
}
}
3. The "delegator"
// delegator class to adapt from/to list with only 1 item
public class ProjectDelegator {
// nice constant to express the intent as clearly as possible
private static final int MY_ONLY_COMPANY = 0;
// our delegate
private Project project;
public ProjectDelegator(Project project) {
this.project = project;
}
// BeanFieldGroup will use this by reflection to bind the "company.name" field
public Company getCompany() {
// delegate the accessing to the origina product
return project.getCompanies().get(MY_ONLY_COMPANY);
}
// accessor; can if not required at a later time
public Project getProject() {
return project;
}
}
4. The legacy model classes
// our problem class
public class Project {
private String name;
private List<Company> companies = new ArrayList<>();
public Project(String name, Company company) {
this.name = name;
companies.add(company);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Company> getCompanies() {
return companies;
}
public void setCompanies(List<Company> companies) {
this.companies = companies;
}
}
// the "indirect" problem :)
public class Company {
private String name;
public Company(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("Setting actual company name to [" + name + "]");
this.name = name;
}
}
5. Resulting UI
6. Pressing the save button
Setting actual company name to [myNewCompany]

Related

"How to add elements to list"

I am trying to add element in a list from a different method but i am not able to do.
When I am using static keyword in list then i am able to add. I don't understand how it is working.
WITH STATIC
public class QuotesController : ApiController
{
static List<Quote> quotes = new List<Quote>()
{
new Quote(){Id=0,Author="ram",Description="hhkhkhh",Title="gjgj" },
new Quote(){Id=1,Author="shyam",Description="ououo",Title="ouo" }
};
[HttpGet]
public IEnumerable<Quote> Get()
{
return quotes;
}
public void Post([FromBody]Quote quote)
{
quotes.Add(quote);
}
}
I expect the item to be added in list without using static.

how to create a viewmodel and map for the edmx designer class

can anybody provide a link for creating a viewmodel for the edmx designer class
suppose my edmx file is named School.edmx and it has school.Designer.cs class.
In the designer class i have the folowing entity object
[EdmEntityTypeAttribute(NamespaceName="teamworkModel", Name="User")]
[Serializable()]
[DataContractAttribute(IsReference=true)]
public partial class User : EntityObject
{
#region Primitive Properties
[EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
[DataMemberAttribute()]
public global::System.Int32 User_Pk
{
get
{
return _User_Pk;
}
set
{
if (_User_Pk != value)
{
OnUser_PkChanging(value);
ReportPropertyChanging("User_Pk");
_User_Pk = StructuralObject.SetValidValue(value);
ReportPropertyChanged("User_Pk");
OnUser_PkChanged();
}
}
}
private global::System.Int32 _User_Pk;
partial void OnUser_PkChanging(global::System.Int32 value);
partial void OnUser_PkChanged();
[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
[DataMemberAttribute()]
[Required(ErrorMessage="Please enter your name")]
[StringLength(20,ErrorMessage="Name cannot exceed 20 characters")]
[RegularExpression(#"^([a-zA-Z0-9 \.\&\'\-]+)$", ErrorMessage = "Invalid name")]
public global::System.String User_Name
{
get
{
return _User_Name;
}
set
{
OnUser_NameChanging(value);
ReportPropertyChanging("User_Name");
_User_Name = StructuralObject.SetValidValue(value, false);
ReportPropertyChanged("User_Name");
OnUser_NameChanged();
}
}
private global::System.String _User_Name;
partial void OnUser_NameChanging(global::System.String value);
partial void OnUser_NameChanged();
[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
[DataMemberAttribute()]
[Email(ErrorMessage="Invalid email address")]
[Required(ErrorMessage="Please enter email address")]
public global::System.String User_Mail_Id
{
get
{
return _User_Mail_Id;
}
set
{
OnUser_Mail_IdChanging(value);
ReportPropertyChanging("User_Mail_Id");
_User_Mail_Id = StructuralObject.SetValidValue(value, false);
ReportPropertyChanged("User_Mail_Id");
OnUser_Mail_IdChanged();
}
}
private global::System.String _User_Mail_Id;
partial void OnUser_Mail_IdChanging(global::System.String value);
partial void OnUser_Mail_IdChanged();
[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
[DataMemberAttribute()]
[Required(ErrorMessage="Please enter password")]
[StringLength(20,ErrorMessage="Password cannot exceed 20 characters")]
[RegularExpression(#"^([a-zA-Z0-9 \.\&\'\-]+)$", ErrorMessage = "Invalid password")]
public global::System.String User_Password
{
get
{
return _User_Password;
}
set
{
OnUser_PasswordChanging(value);
ReportPropertyChanging("User_Password");
_User_Password = StructuralObject.SetValidValue(value, false);
ReportPropertyChanged("User_Password");
OnUser_PasswordChanged();
}
}
private global::System.String _User_Password;
partial void OnUser_PasswordChanging(global::System.String value);
partial void OnUser_PasswordChanged();
[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
[DataMemberAttribute()]
public global::System.DateTime User_Creation_Date
{
get
{
return _User_Creation_Date;
}
set
{
OnUser_Creation_DateChanging(value);
ReportPropertyChanging("User_Creation_Date");
_User_Creation_Date = StructuralObject.SetValidValue(value);
ReportPropertyChanged("User_Creation_Date");
OnUser_Creation_DateChanged();
}
}
private global::System.DateTime _User_Creation_Date;
partial void OnUser_Creation_DateChanging(global::System.DateTime value);
partial void OnUser_Creation_DateChanged();
I have the following columns in the above entity object (User table)User_PK,User_Name,User_Password,User_Email_ID.....
Please can anyone suggest how to create a viewmodel for the above entity object that contains all the above columns except User_Password and User_Email_ID because i need to use it as strongly typed viewmodel for my view.I also need to use another table in the same viewmodel with selected columns....
i had gone through a lot of documents..i already spent 1 and half day for this
can anybody help..
i know this question is asked repeatedly but i cannt find the right way in doing it...
Thanks
Edit: Modified to answer comment about extra properties from other Entities
This may help
public class UserViewModel
{
public int Pk{get;private set;}
public string Name{get;set;}
public DateTime CreationDate{get;set;}
public string ProjectName{get;set;}
public DateTime ProjectCreated{get;set;}
}
The ViewModel is a flattened version of you entities.
You have to write your viewmodel classes yourself.
Just create a class called something like MyWebApp.Models.User which contains the properties you need and map the edmx class to it in your controller.
For mapping i recommend using the automapper which makes mapping life easier.
EDIT
This is how you use automapper:
Say your DAL class is called User and your viewmodel class is called UserViewModel.
You have to tell automapper once which classes you want to map:
AutoMapper.Mapper.CreateMap<User, UserViewModel>();
Then you can map objects from one type to another with a single line:
User user = dal.GetUser();
UserViewModel model = AutoMapper.Mapper.Map<User, UserViewModel>(user);
Automapper can even map collections of objects. So if your model has a property like IEnumerable<Projects> it will map this as well.
I get VS to do most of the work for me by right clicking on the edmx design surface and selecting Add Code Generation Item > EF 5.x DBContext Generator > Add.
You should then see a [xxx].tt file in the same folder as your edmx file. If you expand this file you should see a POCO class for each of your entities.
I copy the entities as required into my viewmodel and delete the ones I don't need.
Once I'm happy with my viewmodel I delete the [xx].tt file, right click properties on the edmx design surface > Properties > Code Generation strategy > default.
I'd also highly recommend using Automapper as Jan mentioned in his answer.

JSF 2.0 + Primefaces richtext editor

<p:editor value="#{editorBean.value}" widgetVar="editor" width="686"
height="390" language="en" align="center">
</p:editor>
Following is my rich-text editor bean picked up from primefaces
#ManagedBean(name = "editorBean")
#SessionScoped
public class EditorBean {
private static final String MANAGED_BEAN_NAME = "editorBean";
private String value;
public static EditorBean getCurrentInstance() {
return (EditorBean) FacesContext.getCurrentInstance()
.getExternalContext().getRequestMap().get(MANAGED_BEAN_NAME);
}
public void setValue(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
Apart from this I have another bean say A. I have a method inside A that populates a HTML table. What I want is when the user opens the editor, it should be pre-populated with that HTML table data and of course the changes should get reflected into (String: value). Therefore, you can say that I am trying to tie up both the values together. I think it needs to be done with DI but somehow its not working. If someone can guide or quote an example, it would be really helpful.
One way to do it is rewrite your getValue() method to pick up the value from bean A.
And yes, the reference to your A bean should come from DI:
//injecting a reference to A
#ManagedPropery(value="#{A}") //or whatever is the name of your bean
private A beanA;
public void setBeanA(A beanA) {
this.beanA = beanA;
}
Or, with CDI, just:
#Inject private A beanA
Finally, your getValue method
public String getValue() {
return beanA.getValue()
}

How To Prepopulate Checkboxes With Struts2 and Jquery?

I am trying to determine the best/easiest way to prepopulate certain checkboxes created using Struts2 form tags. My application is a "normal" three tier setup, using Struts2 on the controller layer.
Before I really, really dig deep here, does the tag support creating the list of all possible checkboxes, then populating it (say, via the below action)?
Sample action:
public class UserManagementAction extends ActionSupport implements Preparable {
private List<String> allRoles;
private List<String> rolesToPrepopulate;
// get/set methods
public void prepare() throws Exception {
// populate the allRoles and rolesToPrepopulate lists
}
public String execute() throws Exception {
return INPUT;
}
(Note: assume that struts.xml has been configured with which JSP to return for INPUT)
Thanks for any help.
Jason
What I would do is a new object class and use it as for checkboxes.
For example:
public class StrutsCheckbox {
private Integer id;
private Boolean selected;
...
}
And in prepare() method you can set selected field as you wish (and also id to all of them).
Next in JSP:
<s:iterator value="allRoles">
<s:checkbox name="selected" id="selected" fieldValue="%{id}" value="%{selected}"/>
</s:iterator>
And then in submit action Collection selected will be filled with ids.
public class UserManagementAction extends ActionSupport implements Preparable {
private List<StrutsCheckbox> allRoles;
private List<StrutsCheckbox> rolesToPrepopulate;
private List<Integer> selectedCheckboxes;
// get/set methods
public void prepare() throws Exception {
// populate the allRoles and rolesToPrepopulate lists
// fill and set allRoles and/or rolesToPrepopulate
}
public String execute() throws Exception {
return INPUT;
}
public String submit() throws Exception {
// list selectedCheckboxes is filled with selected fields id's
return INPUT;
}
Maybe with some corrections it will work, but the main idea is here.

S#arp Architecture Fluent mapping for self referencing entity (Tree structure)

I've come up against a problem in converting my Fluent NH mapping to Sharp Architecture. I like the platform for it's ease, however it seems to handle entity mappings slightly differently to pure Fluent NH.
I have a Entity 'Category' that is a simple tree structure. I have to override the auto-mapping as there is a M:M property that I need to add in (not included in code below).
When I create tests on the repository, the GetAll method returns all Categories as it should, however the Children property just infinitely loops itself. i.e. the list of children for each category only contains itself, in and unending loop.
/// The Entity ///
public class Category : Entity
{
public Category()
{
InitMembers();
}
/// <summary>
/// Creates valid domain object
/// </summary>
public Category(string name)
: this()
{
Name = name;
}
/// <summary>
/// Creates valid domain object
/// </summary>
public Category(string name, int depth)
: this()
{
Name = name;
Depth = depth;
}
private void InitMembers()
{
Children = new List<Category>();
}
[DomainSignature]
[NotNullNotEmpty]
public virtual string Name { get; protected set; }
[DomainSignature]
public virtual int Depth { get; protected set; }
public virtual Category Parent { get; set; }
public virtual IList<Category> Children { get; private set; }
public virtual void AddChild(Category category)
{
category.Parent = this;
Children.Add(category);
}
}
/// The Mapping ///
public class CategoryMap : IAutoMappingOverride<Category>
{
public void Override(AutoMap<Category> mapping)
{
mapping.Id(x => x.Id, "CategoryId")
.WithUnsavedValue(0)
.GeneratedBy.Identity();
mapping.Map(x => x.Name).WithLengthOf(50);
mapping.Map(x => x.Depth);
mapping.HasMany<Category>(x => x.Children)
.Inverse()
.Cascade.All()
.KeyColumnNames.Add("Parent_id")
.AsBag();
}
}
/// The Data Repository Tests ///
[TestFixture]
[Category("DB Tests")]
public class CategoryRepositoryTests : RepositoryTestsBase
{
private readonly IRepository<Category> _repository = new Repository<Category>();
protected override void LoadTestData()
{
CreatePersistedCategory("Root 1");
CreatePersistedCategory("Root 2");
CreatePersistedCategoryWithChildren("Level 1", "Level 2", "Level 3");
}
[Test]
public void CanGetAllCategories()
{
var categories = _repository.GetAll();
categories.ShouldNotBeNull();
categories.Count.ShouldEqual(5);
}
[Test]
public void CanGetCategoryById()
{
var category = _repository.Get(1);
category.Name.ShouldEqual("Root 1");
category.Depth.ShouldEqual(1);
}
[Test]
public void CanGetCategoryChildren()
{
var category = _repository.Get(3);
category.Name.ShouldEqual("Level 1");
category.Depth.ShouldEqual(1);
category.Children.ShouldNotBeNull();
category.Children.Count.ShouldEqual(1);
category.Children[0].Name.ShouldEqual("Level 2");
category.Children[0].Depth.ShouldEqual(2);
category.Children[0].Children.ShouldNotBeNull();
category.Children[0].Children.Count.ShouldEqual(1);
category.Children[0].Children[0].Name.ShouldEqual("Level 3");
category.Children[0].Children[0].Depth.ShouldEqual(3);
}
private void CreatePersistedCategory(string categoryName)
{
var category = new Category(categoryName, 1);
_repository.SaveOrUpdate(category);
FlushSessionAndEvict(category);
}
private void CreatePersistedCategoryWithChildren(string category1, string category2, string category3)
{
var cat1 = new Category(category1, 1);
var cat2 = new Category(category2, 2) { Parent = cat1 };
var cat3 = new Category(category3, 3) { Parent = cat2 };
cat1.AddChild(cat2);
cat2.AddChild(cat3);
_repository.SaveOrUpdate(cat1);
FlushSessionAndEvict(cat1);
}
}
Managed to work it out, after much Mapping tweaking. The Auto-mapping stuff although very cool requires some understanding. RTFM for me...
Right you are, I hadn't yet discovered or understood the Auto-mapping conventions: TableNameConvention, PrimaryKeyConvention, and specifically HasManyConvention. The default S#arp code likes to pluralise its database tables, and have Id columns with the table name prefixed, i.e. CategoryId.
I don't like to pluralise, and I like consistent Id columns, 'Id' suffices. And my foreign key references were different style to, I like Category_id.
public class HasManyConvention : IHasManyConvention
{
public bool Accept(IOneToManyCollectionInstance oneToManyPart)
{
return true;
}
public void Apply(IOneToManyCollectionInstance oneToManyPart)
{
oneToManyPart.KeyColumnNames.Add(oneToManyPart.EntityType.Name + "_id");
}
}
public class PrimaryKeyConvention : IIdConvention
{
public bool Accept(IIdentityInstance id)
{
return true;
}
public void Apply(IIdentityInstance id)
{
id.Column("Id");
}
}
However now this all works a treat but I now have a problem with Many-to-many mappings. It seems S#arp doesn't quite support them yet. My mapping overrides don't seem to work, nothing gets inserted into my mapping table in the database.
See: S#arp Architecture many-to-many mapping overrides not working
I was not able to solve this using fluent conventions and from what I have seen searching around this currently can't be done using conventions. Fluent assumes that a self-referencing tree like this is many-to-many, so in your case I assume you are trying to map a many-to-many relationship and so there should be no problem.
In my case I needed to map it as many-to-one (for a strict hierarchy of nested comments and replies). The only way I could figure out to do this was setting an override for the parent-child class to map that relationship. Fortunately it is very easy.
I would love to know if there is a way to successfully map many-to-one like this with conventions though.

Resources