How to add songs to album entity in springboot? - postgresql

Please help me with the logic.
Is it possible to save data in multiple entities simultaneously? I f yes then how?
Also I have to do same with the singer entity i.e. add singer data to song entity...does it require the same logic or a different one.
The code for entities is as follows:
Album entity
#Entity
#Table(name = "albums")
public class AlbumEntity extends ApplicationPersistenceEntity implements Album {
#Id
#Column(name = "album_id")
#NotNull
private long albumId;
#NotEmpty
#Column(name = "NAME")
private String albumName;
#NotEmpty
#Column(name = "Genre")
private String genre;
#Column(name = "album_release_date", columnDefinition = "DATE", nullable = false)
#DateTimeFormat(pattern = "yyyy-MM-dd")
private Date albumreleaseDate;
#ManyToOne(cascade = CascadeType.ALL, optional = false, fetch = FetchType.LAZY)
#JoinColumn(name = "singer_id", nullable = false)
private SingerEntity singer;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "album")
#Fetch(FetchMode.JOIN)
private List<SongEntity> songs;
private static final long serialVersionUID = 1L;
/**
* The constructor.
*/
public AlbumEntity() {
}
/**
* The constructor.
*
* #param albumId
* #param albumName
* #param genre
* #param albumreleaseDate
* #param singer
* #param songs
*/
public AlbumEntity(long albumId, String albumName, String genre, Date albumreleaseDate, SingerEntity singer,
List<SongEntity> songs) {
super();
this.albumId = albumId;
this.albumName = albumName;
this.genre = genre;
this.albumreleaseDate = albumreleaseDate;
this.singer = singer;
this.songs = songs;
}
/**
* #return albumId
*/
#Override
public long getAlbumId() {
return this.albumId;
}
/**
* #param albumId new value of {#link #getalbumId}.
*/
#Override
public void setAlbumId(long albumId) {
this.albumId = albumId;
}
/**
* #return albumName
*/
#Override
public String getAlbumName() {
return this.albumName;
}
/**
* #param albumName new value of {#link #getalbumName}.
*/
#Override
public void setAlbumName(String albumName) {
this.albumName = albumName;
}
/**
* #return genre
*/
#Override
public String getGenre() {
return this.genre;
}
/**
* #param genre new value of {#link #getgenre}.
*/
#Override
public void setGenre(String genre) {
this.genre = genre;
}
/**
* #return albumreleaseDate
*/
#Override
public Date getAlbumreleaseDate() {
return this.albumreleaseDate;
}
/**
* #param albumreleaseDate new value of {#link #getalbumreleaseDate}.
*/
#Override
public void setAlbumreleaseDate(Date albumreleaseDate) {
this.albumreleaseDate = albumreleaseDate;
}
/**
* #return singer
*/
public SingerEntity getSinger() {
return this.singer;
}
/**
* #param singer new value of {#link #getsinger}.
*/
public void setSinger(SingerEntity singer) {
this.singer = singer;
}
/**
* #return songs
*/
public List<SongEntity> getSongs() {
return this.songs;
}
/**
* #param songs new value of {#link #getsongs}.
*/
public void setSongs(List<SongEntity> songs) {
this.songs = songs;
}
#Override
#Transient
public Long getSingerId() {
if (this.singer == null) {
return null;
}
return this.singer.getId();
}
#Override
public void setSingerId(Long singerId) {
if (singerId == null) {
this.singer = null;
} else {
SingerEntity singerEntity = new SingerEntity();
singerEntity.setId(singerId);
this.singer = singerEntity;
}
}
#Override
public String toString() {
return "AlbumEntity [albumId=" + this.albumId + ", albumName=" + this.albumName + ", genre=" + this.genre
+ ", albumreleaseDate=" + this.albumreleaseDate + ", singer=" + this.singer + ", songs=" + this.songs + "]";
}
}
Song entity
#Entity
#Table(name = "songs")
public class SongEntity extends ApplicationPersistenceEntity implements Song {
#Id
#Column(name = "song_id")
// #GeneratedValue(strategy = GenerationType.TABLE)
private long songId;
#Column(name = "Title")
private String title;
#Column(name = "duration")
private float duration;
/**
* #return duration
*/
#Override
public float getDuration() {
return this.duration;
}
/**
* #param duration new value of {#link #getduration}.
*/
#Override
public void setDuration(float duration) {
this.duration = duration;
}
#ManyToOne(cascade = CascadeType.PERSIST, optional = false, fetch = FetchType.LAZY)
#JoinColumn(name = "singer_id", nullable = false)
private SingerEntity singer;
#ManyToOne(cascade = CascadeType.ALL, optional = true, fetch = FetchType.LAZY)
#JoinColumn(name = "album_id")
private AlbumEntity album;
private static final long serialVersionUID = 1L;
/**
* The constructor.
*/
public SongEntity() {
}
/**
* The constructor.
*
* #param songId
* #param title
* #param content
* #param singer
* #param album
*/
public SongEntity(long songId, String title, SingerEntity singer, AlbumEntity album) {
super();
this.songId = songId;
this.title = title;
this.singer = singer;
this.album = album;
}
/**
* #return songId
*/
#Override
public long getSongId() {
return this.songId;
}
/**
* #param songId new value of {#link #getsongId}.
*/
#Override
public void setSongId(long songId) {
this.songId = songId;
}
/**
* #return title
*/
#Override
public String getTitle() {
return this.title;
}
/**
* #param title new value of {#link #gettitle}.
*/
#Override
public void setTitle(String title) {
this.title = title;
}
/**
* #return singer
*/
public SingerEntity getSinger() {
return this.singer;
}
/**
* #param singer new value of {#link #getsinger}.
*/
public void setSinger(SingerEntity singer) {
this.singer = singer;
}
/**
* #return album
*/
public AlbumEntity getAlbum() {
return this.album;
}
/**
* #param album new value of {#link #getalbum}.
*/
public void setAlbum(AlbumEntity album) {
this.album = album;
}
#Override
#Transient
public Long getSingerId() {
if (this.singer == null) {
return null;
}
return this.singer.getId();
}
#Override
public void setSingerId(Long singerId) {
if (singerId == null) {
this.singer = null;
} else {
SingerEntity singerEntity = new SingerEntity();
singerEntity.setId(singerId);
this.singer = singerEntity;
}
}
#Override
#Transient
public Long getAlbumId() {
if (this.album == null) {
return null;
}
return this.album.getId();
}
#Override
public void setAlbumId(Long albumId) {
if (albumId == null) {
this.album = null;
} else {
AlbumEntity albumEntity = new AlbumEntity();
albumEntity.setId(albumId);
this.album = albumEntity;
}
}
#Override
public String toString() {
return "SongEntity [songId=" + this.songId + ", title=" + this.title + ", duration=" + this.duration + ", singer="
+ this.singer + ", album=" + this.album + "]";
}
}
Singer Entity
#Entity
#Table(name = "singers")
public class SingerEntity extends ApplicationPersistenceEntity implements Singer {
#Id
#Column(name = "singer_id")
private long singerId;
#NotEmpty
#Column(name = "singer_name")
private String singerName;
#NotEmpty
#Column(name = "Gender")
private String gender;
#Column(name = "birth_date", columnDefinition = "DATE", nullable = false)
#JsonFormat(pattern = "yyyy-MM-dd")
private Date birthDate;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "singer")
private List<SongEntity> songs;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "singer")
private List<AlbumEntity> albums;
private static final long serialVersionUID = 1L;
/**
* The constructor.
*/
public SingerEntity() {
}
/**
* The constructor.
*
* #param singerId
* #param firstname
* #param lastname
* #param gender
* #param songs
* #param albums
*/
public SingerEntity(long singerId, String singerName, String gender, Date birthDate, List<SongEntity> songs,
List<AlbumEntity> albums) {
super();
this.singerId = singerId;
this.singerName = singerName;
this.gender = gender;
this.birthDate = birthDate;
this.songs = songs;
this.albums = albums;
}
/**
* #return singerId
*/
#Override
public long getSingerId() {
return this.singerId;
}
/**
* #param singerId new value of {#link #getsingerId}.
*/
#Override
public void setSingerId(long singerId) {
this.singerId = singerId;
}
/**
* #return firstname
*/
#Override
public String getSingerName() {
return this.singerName;
}
/**
* #param singername new value of {#link #getsingername}.
*/
#Override
public void setSingerName(String singerName) {
this.singerName = singerName;
}
/**
* #return gender
*/
#Override
public String getGender() {
return this.gender;
}
/**
* #param gender new value of {#link #getgender}.
*/
#Override
public void setGender(String gender) {
this.gender = gender;
}
/**
* #return birthDate
*/
#Override
public Date getBirthDate() {
return this.birthDate;
}
/**
* #param birthDate new value of {#link #getbirthDate}.
*/
#Override
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
/**
* #return songs
*/
public List<SongEntity> getSongs() {
return this.songs;
}
/**
* #param songs new value of {#link #getsongs}.
*/
public void setSongs(List<SongEntity> songs) {
this.songs = songs;
}
/**
* #return albums
*/
public List<AlbumEntity> getAlbums() {
return this.albums;
}
/**
* #param albums new value of {#link #getalbums}.
*/
public void setAlbums(List<AlbumEntity> albums) {
this.albums = albums;
}
#Override
public String toString() {
return "SingerEntity [singerId=" + this.singerId + ", singerName=" + this.singerName + ", gender=" + this.gender
+ ", birthDate=" + this.birthDate + ", songs=" + this.songs + ", albums=" + this.albums + "]";
}
}
I want to add songs to album table.
But I am not able to figure out the logic to do this.
I want that when I send data from post man like
{
"id": 102,
"albumId": 102,
"albumName": "HS1",
"genre": "Pop",
"singerId":202,
"songs":[
{
"id": 302,
"songId": 302,
"title": "Bad blood",
"singerId": 201,
"duration": 3.76
},
{
"id": 303,
"songId": 303,
"title": "Happy",
"singerId": 202,
"duration": 3.54
}
],
"albumreleaseDate":"2019-05-16"
}
Then the data should be saved in album and song table respectively
example table

I'm confused from your example data. First, I thought it's a POST for album, because it contains all the information of the album and singerID. Then I saw it also contains all information for the song. Which would imply that the song is also to be created.
So this is what I would do:
Create an album:
Request:
POST /album
{
"id": 1,
"genre": "Pop",
"name": "SomeFancyName",
"singerId": 12,
"songs": [
3,
5,
6,
15//...
]
}
Here you will verify the existence of all songs by their ID and return 404 if a song does not exist
Response:
201 Created
Headers: Location: "/ablums/{albumId}"
Add songs to an album
Request:
PATCH /album/{albumId}/songs
{
"songs": [
7,
19,
21,
13//...
]
}
Again verify the existence of all songs by their ID and return 404 if a song does not exist.
Response:
204 No Content
Delete song from album
Same as 2. just use DELETE method instead of PATCH
Songs and Singer would get their own endpoints accordingly and you only reference them by their ids in requests. Because, when you do a POST on album and add full song data, you either also create the song and have to think about what to do if the song already exists or send unnecessary data since the id should be enough to identify the song.
Basically, you add too much complexity to one endpoint

Related

Calendar object won't update in database but does update within session

I'm representing Appointments in an entity bean which have a startTime and endTime of type Calendar. This is stored using JPA as TIMESTAMP. If I edit the Appointment object's start / end time it updates on the object itself during the session but it's not updated within the database itself. Other elements such as the Appointment's description successfully update in the database.. It's only he start and end time which are not.
Entity class (this is indirectly updated in the database with EntityManager.merge():
package mcknighte.entity;
import java.io.Serializable;
import java.util.Calendar;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Temporal;
import static javax.persistence.TemporalType.TIMESTAMP;
import javax.validation.constraints.NotNull;
import mcknighte.common.Convertable;
/**
* Appointment entity class, to represent an Appointment within the database
* and throughout the application
*
* #author Edward McKnight (UP608985)
* #see Client
* #see AppointmentFacade
* #see AppointmentService
* #see AppointmentController
* #since 2017
* #version 1.0
*/
#Entity
public class Appointment implements Serializable, Convertable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#NotNull
#Temporal(TIMESTAMP)
private Calendar startTime;
#NotNull
#Temporal(TIMESTAMP)
private Calendar endTime;
#NotNull
private String description;
#NotNull
#ManyToOne(targetEntity = Client.class)
private Client creator;
#NotNull
#OneToMany(targetEntity = Client.class)
private List<Client> attendees;
/**
* Constructor
*/
public Appointment() {
this.startTime = Calendar.getInstance();
this.endTime = Calendar.getInstance();
}
/**
* Get the attendees for the appointment
*
* #return a list of attendees for the appointment
*/
public List<Client> getAttendees() {
return attendees;
}
/**
* Set the attendees for the appointment
*
* #param attendees a list of attendees for the appointment
*/
public void setAttendees(List<Client> attendees) {
this.attendees = attendees;
}
/**
* Get the creator of the appointment
*
* #return the creator of the appointment
*/
public Client getCreator() {
return creator;
}
/**
* Set the creator of the appointment
*
* #param creator the creator of the appointment
*/
public void setCreator(Client creator) {
this.creator = creator;
}
/**
* Get the description for the appointment
*
* #return the description for the appointment
*/
public String getDescription() {
return description;
}
/**
* Set the description for the appointment
*
* #param description the description for the appointment
*/
public void setDescription(String description) {
this.description = description;
}
/**
* Get the end time of the appointment
*
* #return the end time of the appointment
*/
public Calendar getEndTime() {
return endTime;
}
/**
* Set the end time of the appointment
*
* #param end the end time of the appointment
*/
public void setEndTime(Calendar end) {
this.endTime = end;
}
/**
* Get the start time of the appointment
*
* #return the start time of the appointment
*/
public Calendar getStartTime() {
return startTime;
}
/**
* Set the start time of the appointment
*
* #param start the start time of the appointment
*/
public void setStartTime(Calendar start) {
this.startTime = start;
}
/**
* Get the ID for the appointment
*
* #return the ID for the appointment
*/
#Override
public Long getId() {
return id;
}
/**
* Set the ID for the appointment
*
* #param id the ID for the appointment
*/
public void setId(Long id) {
this.id = id;
}
/**
* Hash code
*
* #return int
*/
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
/**
* Equals
*
* #param object the object to compare to
* #return whether or not this equals the object being compared to
*/
#Override
public boolean equals(Object object) {
if (!(object instanceof Appointment)) {
return false;
}
Appointment other = (Appointment) object;
return !((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id)));
}
/**
* Represent this object as a string
*
* #return a string representation of this object
*/
#Override
public String toString() {
return "mcknighte.entity.Appointment[ id=" + id + " ]";
}
}
The issue has been resolved after finding another StackOverflow question and reading the Oracle documentation.
All that needed to be done was to add an #Mutable annotation to each of the Calendar properties, as Date and Calendar are immutable by default.

JPA #Id annoation

i want to insert into a table with a specified value,but it just don't work,
here is my code:
#Id
#Column(insertable=true,updatable=true)
public Long getS_id() {
return s_id;
}
#Resource(name="studentService")
private StudentService stus;
Student student = new Student();
student.setS_id(123213L);
student.setName("vincent");
stus.add(student);
If I change:
#Id
#Column(insertable=true,updatable=true)
public Long getS_id() {
return s_id;
}
to this:
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(insertable=true,updatable=true)
public Long getS_id() {
return s_id;
}
and don't set s_id manualy it works well.
here my student class
#Entity()
#Table(name="stu_info")
public class Student implements Serializable{
private static final long serialVersionUID = 1L;
/**
* 学生的学号
*/
private Long s_id;
/**
* 学生姓名
*/
private String name;
/**
* 学生性别
*/
private String sex;
/**
* 学生生日
*/
private Date birthday;
/**
* 学生电话号码
*/
private String telephone;
/**
* 学生所在年级
*/
private String grade;
/**
* 学生所在班级
*/
private String classes;
/**
* 学生编号
*/
private int number;
/**
* 学生父亲姓名
*/
private String father_name;
/**
* 学生母亲姓名
*/
private String mother_name;
/**
* 学生个人疾病史
*/
private String diseases_history;
#Id
#Column(insertable=true,updatable=true)
public Long getS_id() {
return s_id;
}
public void setS_id(Long s_id) {
this.s_id = s_id;
}
#Column(length=32)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Column(length=12)
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
#Temporal(TemporalType.DATE)
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
#Column(length=12)
public String getTelephone() {
return telephone;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
#Column(length=32)
public String getGrade() {
return grade;
}
public void setGrade(String grade) {
this.grade = grade;
}
#Column(length=32)
public String getClasses() {
return classes;
}
public void setClasses(String classes) {
this.classes = classes;
}
#Column(length=32)
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
#Column(length=32)
public String getFather_name() {
return father_name;
}
public void setFather_name(String father_name) {
this.father_name = father_name;
}
#Column(length=32)
public String getMother_name() {
return mother_name;
}
public void setMother_name(String mother_name) {
this.mother_name = mother_name;
}
#Column(length=32)
public String getDiseases_history() {
return diseases_history;
}
public void setDiseases_history(String diseases_history) {
this.diseases_history = diseases_history;
}
}
From the limited information posted I would guess you are using SQL Server and to insert a record into an SQLServer table with an explicit value defined for an Identity column requires you to turn on identity inserts for that table.
https://msdn.microsoft.com/en-gb/library/ms188059.aspx
So if you run the above against your table you should then be able to persist using a specific value.
So not really anything to do with JPA.

Error Iterable Implementation GWTP-Rest Jackson

I use GWT 2.6.1 with GWTP-Rest Api, when i compile, i get an error.
My class Page implements Iterable & Serializable. This class come from the spring framework but was adaptable to GWT (this class is use by an other project which works with RPC. The error comes from an other class "Sort" which implements the same Interface. See code below.
Error come from com.github.nmorel.gwtjackson.rebind.ObjectMapperGenerator which create an exception.
if I delete the Iterator implementation of OrderMobile, no error occure.
Error in console :
Creating deserializer for **.***.**.**.**.***.*****.Page
[INFO] [ERROR] Wrong number of argument for a java.lang.Iterable implementation
Code from Sort :
public class SortMobile implements Serializable, Iterable<OrderMobile>
{
private static final long serialVersionUID = -8226494389482286795L;
public static final Direction DEFAULT_DIRECTION = Direction.ASC;
private List<OrderMobile> orders = new ArrayList<OrderMobile>();
SortMobile() {
}
/**
* Creates a new {#link Sort} instance using the given {#link Order}s.
*
* #param orders must not be {#literal null}.
*/
public SortMobile(final OrderMobile... orders) {
this(Arrays.asList(orders));
}
/**
* Creates a new {#link SortMobile} instance.
*
* #param list must not be {#literal null} or contain {#literal null}.
*/
public SortMobile(final List<OrderMobile> list) {
if (null == list || list.isEmpty()) {
throw new IllegalArgumentException("You have to provide at least one sort property to sort by!");
}
this.orders = list;
}
/**
* Creates a new {#link SortMobile} instance. Order defaults to {#value Direction#ASC}.
*
* #param properties must not be {#literal null} or contain {#literal null} or empty strings
*/
public SortMobile(final String... properties) {
this(DEFAULT_DIRECTION, properties);
}
/**
* Creates a new {#link SortMobile} instance.
*
* #param direction defaults to {#linke Sort#DEFAULT_DIRECTION} (for {#literal null} cases, too)
* #param properties must not be {#literal null} or contain {#literal null} or empty strings
*/
public SortMobile(final Direction direction, final String... properties) {
this(direction, properties == null ? new ArrayList<String>() : Arrays.asList(properties));
}
/**
* Creates a new {#link SortMobile} instance.
*
* #param direction
* #param properties
*/
public SortMobile(final Direction direction, final List<String> properties) {
if (properties == null || properties.isEmpty()) {
throw new IllegalArgumentException("You have to provide at least one property to sort by!");
}
this.orders = new ArrayList<OrderMobile>(properties.size());
for (String property : properties) {
this.orders.add(new OrderMobile(direction, property));
}
}
/*
* (non-Javadoc)
*
* #see java.lang.Object#equals(java.lang.Object)
*/
#Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof SortMobile)) {
return false;
}
SortMobile that = (SortMobile) obj;
return this.orders.equals(that.orders);
}
/*
* (non-Javadoc)
*
* #see java.lang.Object#hashCode()
*/
#Override
public int hashCode() {
int result = 17;
result = 31 * result + orders.hashCode();
return result;
}
// GETTER SETTER
public void setOrders(final List<OrderMobile> orders) {
this.orders = orders;
}
public List<OrderMobile> getOrders() {
return orders;
}
public static Direction getDefaultDirection() {
return DEFAULT_DIRECTION;
}
/*
* (non-Javadoc)
*
* #see java.lang.Object#toString()
*/
#Override
public String toString() {
return Arrays.toString(orders.toArray(new OrderMobile[orders.size()]));
}
// ### elements of iterator implementation
#Override
public Iterator<OrderMobile> iterator() {
return this.orders.iterator();
}
/**
* Returns a new {#link Sort} consisting of the {#link Order}s of the current {#link Sort} combined with the given
* ones.
*
* #param sort can be {#literal null}.
* #return
*/
public SortMobile and(final SortMobile sort) {
if (sort == null) {
return this;
}
ArrayList<OrderMobile> these = new ArrayList<OrderMobile>(this.orders);
for (OrderMobile order : sort) {
these.add(order);
}
return new SortMobile(these);
}
/**
* Returns the order registered for the given property.
*
* #param property
* #return
*/
public OrderMobile getOrderFor(final String property) {
for (OrderMobile order : this) {
if (order.getProperty().equals(property)) {
return order;
}
}
return null;
}
}
OrderMobile is a simple dto :
public class OrderMobile implements Serializable {
private static final long serialVersionUID = 1522511010900108987L;
private static final Direction DEFAULT_DIRECTION = Direction.ASC;
private Direction direction;
private String property;
OrderMobile() {
super();
}
/**
* Creates a new {#link OrderMobile} instance. if order is {#literal null} then order defaults to
* {#link SortMobile#DEFAULT_DIRECTION}
*
* #param direction can be {#literal null}, will default to {#link SortMobile#DEFAULT_DIRECTION}
* #param property must not be {#literal null} or empty.
*/
public OrderMobile(final Direction direction, final String property) {
if (!hasText(property)) {
throw new IllegalArgumentException("Property must not null or empty!");
}
this.direction = direction == null ? DEFAULT_DIRECTION : direction;
this.property = property;
}
private boolean hasText(final String s) {
return s != null && s.trim().length() > 0;
}
/**
* Creates a new {#link OrderMobile} instance. Takes a single property. Direction defaults to
* {#link SortMobile#DEFAULT_DIRECTION}.
*
* #param property must not be {#literal null} or empty.
*/
public OrderMobile(final String property) {
this(DEFAULT_DIRECTION, property);
}
/**
* Returns the order the property shall be sorted for.
*
* #return
*/
public Direction getDirection() {
return direction;
}
public void setDirection(final Direction direction) {
this.direction = direction;
}
/**
* Returns the property to order for.
*
* #return
*/
public String getProperty() {
return property;
}
public void setProperty(final String property) {
this.property = property;
}
/**
* Returns whether sorting for this property shall be ascending.
*
* #return
*/
public boolean isAscending() {
return this.direction.equals(Direction.ASC);
}
/**
* Returns a new {#link OrderMobile} with the given {#link OrderMobile}.
*
* #param order
* #return
*/
public OrderMobile with(final Direction order) {
return new OrderMobile(order, this.property);
}
/**
* Returns a new {#link SortMobile} instance for the given properties.
*
* #param properties
* #return
*/
public SortMobile withProperties(final String... properties) {
return new SortMobile(this.direction, properties);
}
/*
* (non-Javadoc)
*
* #see java.lang.Object#hashCode()
*/
#Override
public int hashCode() {
int result = 17;
result = 31 * result + direction.hashCode();
result = 31 * result + property.hashCode();
return result;
}
/*
* (non-Javadoc)
*
* #see java.lang.Object#equals(java.lang.Object)
*/
#Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof OrderMobile)) {
return false;
}
OrderMobile that = (OrderMobile) obj;
return this.direction.equals(that.direction) && this.property.equals(that.property);
}
/*
* (non-Javadoc)
*
* #see java.lang.Object#toString()
*/
#Override
public String toString() {
return property + ":" + direction;
}
}
3.Code of Page :
public class PageMobile<T> implements Iterable<T>, Serializable {
private static final long serialVersionUID = 867755909294344406L;
private List<T> content = new ArrayList<T>();
private PageRequestMobile pageable;
private long total;
// for serialization
PageMobile() {
}
/**
* Constructor of {#code Page}.
*
* #param content the content of this page, must not be {#literal null}.
* #param pageable the paging information, can be {#literal null}.
* #param total the total amount of items available
*/
public PageMobile(final List<T> content, final PageRequestMobile pageable, final long total) {
if (null == content) {
throw new IllegalArgumentException("Content must not be null!");
}
this.content.addAll(content);
this.total = total;
this.pageable = pageable;
}
/**
* Creates a new {#link PageMobile} with the given content. This will result in the created {#link PageMobile} being
* identical
* to the entire {#link List}.
*
* #param content must not be {#literal null}.
*/
public PageMobile(final List<T> content) {
this(content, null, null == content ? 0 : content.size());
}
/**
* Returns the number of the current page. Is always non-negative and less that {#code Page#getTotalPages()}.
*
* #return the number of the current page
*/
public int getNumber() {
return pageable == null ? 0 : pageable.getPageNumber();
}
/**
* Returns the size of the page.
*
* #return the size of the page
*/
public int getSize() {
return pageable == null ? 0 : pageable.getPageSize();
}
/*
* (non-Javadoc)
*
* #see org.springframework.data.domain.Page#getTotalPages()
*/
public int getTotalPages() {
return getSize() == 0 ? 0 : (int) Math.ceil((double) total / (double) getSize());
}
/**
* Returns the number of elements currently on this page.
*
* #return the number of elements currently on this page
*/
public int getNumberOfElements() {
return content.size();
}
/**
* Returns the total amount of elements.
*
* #return the total amount of elements
*/
public long getTotalElements() {
return total;
}
/**
* set the total amount of elements.
*
*
*/
public void setTotalElements(final Long total) {
this.total = total;
}
/*
* (non-Javadoc)
*
* #see org.springframework.data.domain.Page#hasPreviousPage()
*/
public boolean hasPreviousPage() {
return getNumber() > 0;
}
/*
* (non-Javadoc)
*
* #see org.springframework.data.domain.Page#isFirstPage()
*/
public boolean isFirstPage() {
return !hasPreviousPage();
}
/*
* (non-Javadoc)
*
* #see org.springframework.data.domain.Page#hasNextPage()
*/
public boolean hasNextPage() {
return (getNumber() + 1) * getSize() < total;
}
/*
* (non-Javadoc)
*
* #see org.springframework.data.domain.Page#isLastPage()
*/
public boolean isLastPage() {
return !hasNextPage();
}
/**
* Returns the page content as {#link List}.
*
* #return
*/
public List<T> getContent() {
return Collections.unmodifiableList(content);
}
/*
* (non-Javadoc)
*
* #see org.springframework.data.domain.Page#hasContent()
*/
public boolean hasContent() {
return !content.isEmpty();
}
/*
* (non-Javadoc)
*
* #see org.springframework.data.domain.Page#getSort()
*/
// FIXME to the version in
public SortMobile getSort() {
return pageable == null ? null : pageable.getSort();
}
/*
* (non-Javadoc)
*
* #see java.lang.Object#toString()
*/
#Override
public String toString() {
String contentType = "UNKNOWN";
if (content.size() > 0) {
contentType = content.get(0).getClass().getName();
}
return "Page " + getNumber() + " of " + getTotalPages() + " containing " + contentType + " instances";
}
/*
* (non-Javadoc)
*
* #see java.lang.Object#equals(java.lang.Object)
*/
#Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof PageMobile<?>)) {
return false;
}
PageMobile<?> that = (PageMobile<?>) obj;
boolean totalEqual = this.total == that.total;
boolean contentEqual = this.content.equals(that.content);
boolean pageableEqual = this.pageable == null ? that.pageable == null : this.pageable.equals(that.pageable);
return totalEqual && contentEqual && pageableEqual;
}
/*
* (non-Javadoc)
*
* #see java.lang.Object#hashCode()
*/
#Override
public int hashCode() {
int result = 17;
result = 31 * result + (int) (total ^ total >>> 32);
result = 31 * result + (pageable == null ? 0 : pageable.hashCode());
result = 31 * result + content.hashCode();
return result;
}
/**
* Adjust the page size, distributing items equally (+/- 1 item) on each page, given a maximum page size.
*
* WARNING: this function reverse pages order.
* TODO: delegate page order reversing to another function, to limit a single behavior for a given function.
*
* #param page The page
* #param request The associated page request
* #param maxPageSize The maximum page size
* #return The new ajusted page
*/
public static <T> PageMobile<T> adjustPageSize(final PageMobile<T> page, final PageRequestMobile request, final int maxPageSize) {
int totalElnts = (int) page.getTotalElements();
int currentPageNumber = request.getPageNumber();
if (totalElnts == 0) {
List<T> newContent = new ArrayList<T>(0);
PageRequestMobile newRequest = new PageRequestMobile(currentPageNumber, maxPageSize);
return new PageMobile<T>(newContent, newRequest, totalElnts);
}
int nbPages = (int) Math.ceil((double) totalElnts / maxPageSize);
int pageSize = totalElnts / nbPages;
int nbOrphans = totalElnts % nbPages;
if (nbOrphans > 0) {
++pageSize;
}
int startIndex = totalElnts;
int endIndex = totalElnts;
for (int pageNumber = 0; pageNumber <= currentPageNumber; ++pageNumber) {
int currentPageSize = nbOrphans == 0 || pageNumber < nbOrphans ? pageSize : pageSize - 1;
startIndex -= currentPageSize;
endIndex = startIndex + currentPageSize;
}
List<T> newContent = page.getContent().subList(startIndex, endIndex);
PageRequestMobile newRequest = new PageRequestMobile(currentPageNumber, pageSize);
return new PageMobile<T>(newContent, newRequest, totalElnts);
}
// GETTER SETTER
public void setContent(final List<T> content) {
this.content = content;
}
public void setPageable(final PageRequestMobile pageable) {
this.pageable = pageable;
}
public PageRequestMobile getPageable() {
return pageable;
}
public long getTotal() {
return total;
}
public void setTotal(final long total)
{
this.total = total;
}
#Override
public Iterator<T> iterator() {
return this.content.iterator();
}
}
Wrapper to response :
public class Result<T> {
protected Boolean error;
protected String errorMessage;
private HashMap<String, String> errorDetails;
private T objectReceive;
public Result()
{
}
/**
* Initialize with the error at true
*
* #param objectReceive : object to transmit
* #param messageError : message error
*/
public Result(final T objectReceive, final String messageError)
{
this.objectReceive = objectReceive;
hasError(messageError);
}
/**
* Initialize with the error at false
*
* #param objectReceive : object to transmit
*/
public Result(final T objectReceive)
{
this.objectReceive = objectReceive;
this.error = false;
}
public void hasError(final String errorMessage)
{
this.errorDetails = new HashMap<String, String>();
this.error = false;
if (errorMessage != null)
{
this.error = true;
this.errorMessage = errorMessage;
}
}
public Result(final String errorMessage)
{
this.errorDetails = new HashMap<String, String>();
this.error = false;
if (errorMessage != null)
{
this.error = true;
this.errorMessage = errorMessage;
}
}
public Result<T> addDetail(final String name, final String value) {
errorDetails.put(name, value);
return this;
}
public Boolean getError() {
return error;
}
public String getErrorMessage() {
return errorMessage;
}
public HashMap<String, String> getErrorDetails() {
return errorDetails;
}
public void setError(final Boolean error) {
this.error = error;
}
public void setErrorDetails(final HashMap<String, String> errorDetails) {
this.errorDetails = errorDetails;
}
public void setErrorMessage(final String errorMessage) {
this.errorMessage = errorMessage;
}
public T getObjectReceive() {
return objectReceive;
}
public void setObjectReceive(final T objectReceive) {
this.objectReceive = objectReceive;
}
}
With the current version of gwt-jackson (0.6.1), what is sure, you won't be able to use SortMobile as a property in a class. I'll look how I can fix it.
gwt-jackson fails to parse SortMobile because it implements directly Iterable<OrderMobile> and not Iterable<T> with SortMobile<T>.
As a workaround, you have a few solutions :
you can declare the property as a Iterable<OrderMobile> in Page. This way, gwt-jackson will use the serializer/deserializer for Iterable but the instance created by the deserializer will be an ArrayList.
change SortMobile to SortMobile<T extends OrderMobile> implements Iterable<T>
declare your own serializer/deserializer for SortMobile by following the wiki.
Edit :
Since version 0.6.2, you should be able to use SortMobile without compilation error.

dijkstra Algorithm Java Implementation with no libraries used

Implementation of Dijkstra's in java without using Comparator interface.
First you can read here the algorithm Pseudocode: http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
End here is one good working impemetation with comparator..but you have to create classes of node , graph etc..
if comparator is your problem just create your own! ;)
static class distance_Comparator implements Comparator<node>
{
public int compare(node x, node y)
{
if(x.getDistance()<y.getDistance())
{
return -1;
}
else if(x.getDistance()>y.getDistance())
{
return 1;
}
return 0;
}
}
And here the Dijkstra
public static void Dijkstra(graph newgraph)
{
System.out.println("--------------------------------------------------------------------------------------");
System.out.println("--------------------------------------------------------------------------------------");
System.out.println("Running Dijkstra . . . .");
System.out.println("--------------------------------------------------------------------------------------");
System.out.println("--------------------------------------------------------------------------------------");
int sum_average_path=0,average_path=0,numberof_paths=0;
long time_a=System.nanoTime();
//[newgraph.getNum_nodes()]; // shortest known distance from "vertex"
//HashMap visited=new HashMap<>();//[newgraph.getNum_nodes()]; // all false initially
//[newgraph.getNum_nodes()]; // preceeding node in path
distance_Comparator comparator=new distance_Comparator();
PriorityQueue<node> queue = new PriorityQueue<node>((int) newgraph.getNumber_of_nodes(),comparator);
///////// find max shortest path : diameter of graph ////////////////
double diameter=-1.0;
int s=0,i=0;
double alt=0;
HashMap map;
///////////find all nodes of graph/////////////////
map=newgraph.getAll_graph_nodes();
for (Object key : map.keySet())
{
i++;
// System.out.println("source node: "+key);
///////////////////Initializations////////////////////////////
/////////////////////////////////////////////////////////////
HashMap distance=new HashMap<>(16,0.6f);
HashMap previous=new HashMap<>(16,0.6f);
node tmpnode=(node)map.get(key);
for (Object key_other : map.keySet())
{
node x_tmpnode=(node)map.get(key_other);
distance.put(key_other, Double.POSITIVE_INFINITY);
x_tmpnode.setDistance(Double.POSITIVE_INFINITY);
x_tmpnode.setVisited(false);
}
tmpnode.setDistance_table(distance);
tmpnode.setPrevious_table(previous);
/////////////////////////////////////end of init//////////////////////////////
tmpnode.setDistance((double)(0));
queue.offer(tmpnode); //add tmp node to PriorityQueue
distance.put(key,(double)(0));
Stack sta=new Stack();
while(queue.isEmpty()==false)
{
Stack stack_prev=new Stack();
node queue_tmpnode=queue.poll(); //min_node(distance,map);////vertex in Q with smallest distance in dist[] and has not been visited;
queue_tmpnode.setVisited(true);
/* if(queue_tmpnode.getPrevious_table()!=null)
{
// System.out.println("pre: "+prev);
Stack tmp=(Stack)tmpnode.getPrevious_table().get(queue_tmpnode.getName());
while(tmp.empty()==false)
{
sta.add(queue_tmpnode.getName());
//System.out.println("pop: "+tmp.pop().toString());
queue_tmpnode=
}
}*/
HashMap queue_tmpnodemap=(HashMap)queue_tmpnode.getMap();
if(queue_tmpnodemap!=null)
{
//////////////find all Neighbours of node queue_tmpnode////////////////////
for (Object v : queue_tmpnodemap.keySet())
{
// System.out.println(" v: "+ v.toString());
node tmpnode_neighbors=(node)map.get(v);
alt=(double)(queue_tmpnode.getDistance()) ;
edge tmp_edge= (edge) (queue_tmpnodemap.get(v)); // dist_between(u, v); --accumulate shortest dist from source
alt+= tmp_edge.getWeight();
if ( (alt < tmpnode_neighbors.getDistance()))
{
tmpnode_neighbors.setDistance(alt); // keep the shortest dist from src to v
distance.put(v, alt);
/*
stack_prev.add(tmpnode_neighbors.getName());
HashMap pre_map=new HashMap();
pre_map.put(queue_tmpnode.getName(), stack_prev);
previous.put(tmpnode_neighbors.getName(), pre_map);
//System.out.println("prev stack: "+stack_prev.size());
tmpnode.setPrevious_table(previous);
* */
if((tmpnode_neighbors.isVisited()==false))
queue.add(tmpnode_neighbors); // Add unvisited v into the Q to be processed
}
}
}
}
HashMap tmp_d=null;
tmp_d=new HashMap();
for(Object x: distance.keySet())
{
if(Double.parseDouble(distance.get(x).toString()) < Double.POSITIVE_INFINITY && Double.parseDouble(distance.get(x).toString())!=0)
{
//System.out.println("U: "+key+"-> V:"+x+" value: "+t_tmpnode.getDistance_table().get(x));
tmp_d.put(x, distance.get(x));
}
}
// System.out.println("V:"+i+" size:"+tmp_d.size()+" capacity:");
distance.clear();
tmpnode.setDistance_table(tmp_d);
}
System.out.println("---------------Dijkstra algorithm-------------");
for (Object key : map.keySet())
{
node tmpnode=(node)map.get(key);
// System.out.println("distance of: "+key.toString()+" , is: ");
//System.out.print("U: "+key);
if(tmpnode.getDistance_table()!= null)
{
//System.out.println(" dipla monopatia: "+(tmpnode.getShortest_paths_number()-tmpnode.getDistance_table().size()));
for(Object x: tmpnode.getDistance_table().keySet())
{
//if(Double.parseDouble(tmpnode.getDistance_table().get(x).toString()) < Double.POSITIVE_INFINITY && Double.parseDouble(tmpnode.getDistance_table().get(x).toString())!=0)
//System.out.println("U: "+key+"-> V:"+x+" value: "+tmpnode.getDistance_table().get(x));
if(diameter < (double)tmpnode.getDistance_table().get(x))
{
diameter= (double)tmpnode.getDistance_table().get(x);
}
sum_average_path+=(double)tmpnode.getDistance_table().get(x);
numberof_paths++;
}
}
System.out.println("\n--------------------------------------------");
for(Object prev: tmpnode.getPrevious_table().keySet())
{
System.out.print("node: "+tmpnode.getName()+" path: ");
HashMap map_prev=(HashMap)tmpnode.getPrevious_table().get(prev);
for(Object prev_path: map_prev.keySet())
{
System.out.println("V: "+prev+" -> "+prev_path+"");
Stack tmp=(Stack) map_prev.get(prev_path);
System.out.println("stacksize: "+tmp.size());
while(tmp.empty()==false)
{
System.out.println("pop: "+tmp.pop().toString());
}
}
}
}
newgraph.setDiameter(diameter);
System.out.println("Graph diameter is: "+newgraph.getDiameter());
System.out.println("average path lenght: "+((double)((double)sum_average_path/(double)numberof_paths)));
long time_b=System.nanoTime();
System.out.println("Dijkstra time: "+(time_b-time_a)+" time in seconds: "+(double)((time_b-time_a)/1000000000.0));
}
class: node.java
import java.util.HashMap;
public class node {
private int name;
private HashMap map;
private double pagerank_old;
private double pagerank_new;
private double point_to_me;
private HashMap point_to_me_table;
private double point_to_other;
private HashMap betweenness;
private double betweenness_ofvertex;
private int num_nodes;
private double cluster_coefficient;
private int index;
private int lowlink;
private int shortest_paths_number;
private double distance;
private boolean visited;
private int hub_score;
private int auth_score;
private HashMap distance_table;
private HashMap previous_table;
//private edge edge;
public node(int name,HashMap map)
{
this.name=name;
this.map=map;
}
public node(int name)
{
this.name=name;
}
/**
* #return the name
*/
public int getName() {
return name;
}
/**
* #param name the name to set
*/
public void setName(int name) {
this.name = name;
}
/**
* #return the map
*/
public HashMap getMap() {
return map;
}
/**
* #param map the map to set
*/
public void setMap(HashMap map) {
this.map = map;
}
/**
* #return the pagerank_old
*/
public double getPagerank_old() {
return pagerank_old;
}
/**
* #param pagerank_old the pagerank_old to set
*/
public void setPagerank_old(double pagerank_old) {
this.pagerank_old = pagerank_old;
}
/**
* #return the pagerank_new
*/
public double getPagerank_new() {
return pagerank_new;
}
/**
* #param pagerank_new the pagerank_new to set
*/
public void setPagerank_new(double pagerank_new) {
this.pagerank_new = pagerank_new;
}
/**
* #return the pont_to_me
*/
public double getPoint_to_me() {
return point_to_me;
}
/**
* #param pont_to_me the pont_to_me to set
*/
public void setPoint_to_me(double pont_to_me) {
this.point_to_me = pont_to_me;
}
/**
* #return the point_to_other
*/
public double getPoint_to_other() {
return point_to_other;
}
/**
* #param point_to_other the point_to_other to set
*/
public void setPoint_to_other(double point_to_other) {
this.point_to_other = point_to_other;
}
/**
* #return the distance
*/
public double getDistance() {
return distance;
}
/**
* #param distance the distance to set
*/
public void setDistance(double distance) {
this.distance = distance;
}
/**
* #return the visited
*/
public boolean isVisited() {
return visited;
}
/**
* #param visited the visited to set
*/
public void setVisited(boolean visited) {
this.visited = visited;
}
/**
* #return the distance_table
*/
public HashMap getDistance_table() {
return distance_table;
}
/**
* #param distance_table the distance_table to set
*/
public void setDistance_table(HashMap distance_table) {
this.distance_table = distance_table;
}
/**
* #return the previous_table
*/
public HashMap getPrevious_table() {
return previous_table;
}
/**
* #param previous_table the previous_table to set
*/
public void setPrevious_table(HashMap previous_table) {
this.previous_table = previous_table;
}
public int getHub_score()
{
return hub_score;
}
public void setHub_score(int sc)
{
this.hub_score=sc;
}
public int getAuth_score()
{
return auth_score;
}
public void setAuth_score(int sc)
{
this.auth_score=sc;
}
/**
* #return the point_to_me_table
*/
public HashMap getPoint_to_me_table() {
return point_to_me_table;
}
/**
* #param point_to_me_table the point_to_me_table to set
*/
public void setPoint_to_me_table(HashMap point_to_me_table) {
this.point_to_me_table = point_to_me_table;
}
/**
* #return the betweenness
*/
public HashMap getBetweenness() {
return betweenness;
}
/**
* #param betweenness the betweenness to set
*/
public void setBetweenness(HashMap betweenness) {
this.betweenness = betweenness;
}
/**
* #return the cluster_coefficient
*/
public double getCluster_coefficient() {
return cluster_coefficient;
}
/**
* #param cluster_coefficient the cluster_coefficient to set
*/
public void setCluster_coefficient(double cluster_coefficient) {
this.cluster_coefficient = cluster_coefficient;
}
/**
* #return the betweenness_ofvertex
*/
public double getBetweenness_ofvertex() {
return betweenness_ofvertex;
}
/**
* #param betweenness_ofvertex the betweenness_ofvertex to set
*/
public void setBetweenness_ofvertex(double betweenness_ofvertex) {
this.betweenness_ofvertex = betweenness_ofvertex;
}
/**
* #return the shortest_paths_number
*/
public int getShortest_paths_number() {
return shortest_paths_number;
}
/**
* #param shortest_paths_number the shortest_paths_number to set
*/
public void setShortest_paths_number(int shortest_paths_number) {
this.shortest_paths_number = shortest_paths_number;
}
/**
* #return the num_nodes
*/
public int getNum_nodes() {
return num_nodes;
}
/**
* #param num_nodes the num_nodes to set
*/
public void setNum_nodes(int num_nodes) {
this.num_nodes = num_nodes;
}
/**
* #return the index
*/
public int getIndex() {
return index;
}
/**
* #param index the index to set
*/
public void setIndex(int index) {
this.index = index;
}
/**
* #return the lowlink
*/
public int getLowlink() {
return lowlink;
}
/**
* #param lowlink the lowlink to set
*/
public void setLowlink(int lowlink) {
this.lowlink = lowlink;
}
}
class: edge
public class edge {
private int a;
private int b;
private double weight;
//private double betweenness;
public edge(int start,int end,double weight){
this.a=start;
this.b=end;
this.weight=weight;
}
/**
* #return the a
*/
public int getA() {
return a;
}
/**
* #param a the a to set
*/
public void setA(int a) {
this.a = a;
}
/**
* #return the b
*/
public int getB() {
return b;
}
/**
* #param b the b to set
*/
public void setB(int b) {
this.b = b;
}
/**
* #return the weight
*/
public double getWeight() {
return weight;
}
/**
* #param weight the weight to set
*/
public void setWeight(double weight) {
this.weight = weight;
}
}
class: graph
import java.util.HashMap;
import java.util.Stack;
public class graph {
private HashMap all_graph_nodes;
private double number_of_nodes;
private double number_of_edges;
private double diameter;
private double average_degre;
private double density;
private int nodeindex;
private Stack tarjanStack;
public graph(HashMap map,double n_nodes,double m_edges)
{
this.all_graph_nodes=map;
this.number_of_nodes=n_nodes;
this.number_of_edges=m_edges;
}
/**
* #return the all_graph_nodes
*/
public HashMap getAll_graph_nodes() {
return all_graph_nodes;
}
/**
* #param all_graph_nodes the all_graph_nodes to set
*/
public void setAll_graph_nodes(HashMap all_graph_nodes) {
this.all_graph_nodes = all_graph_nodes;
}
/**
* #return the number_of_nodes
*/
public double getNumber_of_nodes() {
return number_of_nodes;
}
/**
* #param number_of_nodes the number_of_nodes to set
*/
public void setNumber_of_nodes(double number_of_nodes) {
this.number_of_nodes = number_of_nodes;
}
/**
* #return the number_of_edges
*/
public double getNumber_of_edges() {
return number_of_edges;
}
/**
* #param number_of_edges the number_of_edges to set
*/
public void setNumber_of_edges(double number_of_edges) {
this.number_of_edges = number_of_edges;
}
/**
* #return the diameter
*/
public double getDiameter() {
return diameter;
}
/**
* #param diameter the diameter to set
*/
public void setDiameter(double diameter) {
this.diameter = diameter;
}
/**
* #return the average_degre
*/
public double getAverage_degre() {
return average_degre;
}
/**
* #param average_degre the average_degre to set
*/
public void setAverage_degre(double average_degre) {
this.average_degre = average_degre;
}
/**
* #return the density
*/
public double getDensity() {
return density;
}
/**
* #param density the density to set
*/
public void setDensity(double density) {
this.density = density;
}
/**
* #return the nodeindex
*/
public int getNodeindex() {
return nodeindex;
}
/**
* #param nodeindex the nodeindex to set
*/
public void setNodeindex(int nodeindex) {
this.nodeindex = nodeindex;
}
/**
* #return the tarjanStack
*/
public Stack getTarjanStack() {
return tarjanStack;
}
/**
* #param tarjanStack the tarjanStack to set
*/
public void setTarjanStack(Stack tarjanStack) {
this.tarjanStack = tarjanStack;
}
}

spring-form:options tag with enum

I'm having troubles displaying a dropdown list with the proper values. I'm using the <spring-form:select>, <spring-form:options> and <spring-form:option> tags, and I just can't get it to display the correct options. With the following code, I should only be listing "Option 2", "Option 7", and "Option 8".
*Note - I do NOT want to display every possible Enum value, but for some reason Spring seems to want to display them all. It appears to be completely ignoring the list that is provided to the <spring-form:options> tag.
JSP Tags
<spring-form:select path="selectOptions">
<spring-form:option value="" label="*** Select Option ***" />
<spring-form:options path="${availableOptions}" />
</spring-form:select>
Enum
public enum SelectOptions {
// CHECKSTYLE_OFF: LineLength
/**
* Option 1.
*/
OPTION_1(1, "Option 1"),
/**
* Option 2.
*/
OPTION_2(2, "Option 2"),
/**
* Option 3.
*/
OPTION_3(3, "Option 3"),
/**
* Option 4.
*/
OPTION_4(4, "Option 4"),
/**
* Option 5.
*/
OPTION_5(5, "Option 5"),
/**
* Option 6.
*/
OPTION_6(6, "Option 6"),
/**
* Option 7.
*/
OPTION_7(7, "Option 7"),
/**
* Option 8.
*/
OPTION_8(8, "Option 8"),
/**
* Option 9.
*/
OPTION_9(9, "Option 9"),
/**
* Option 10.
*/
OPTION_10(10, "Option 10");
private int id;
private String description;
/**
* Constructor.
*
* #param id the id
* #param description the description
*/
private SelectOptions(final int id, final String description) {
this.id = id;
this.description = description;
}
/**
* Retrieves the {#link SelectOptions} associated with the passed in id.
*
* #param id the id associated with the SelectOptions
* #return the SelectOptions
*/
public static SelectOptions getInstance(final int id) {
for (final SelectOptions selectOptions : SelectOptions.values()) {
if (selectOptions.id == id) {
return selectOptions;
}
}
throw new IllegalArgumentException("SelectOptions could not be determined with id [" + id + "]");
}
/**
* Retrieves the {#link SelectOptions} associated with the passed in description.
*
* #param description the description associated with the SelectOptions
* #return the SelectOptions
*/
public static SelectOptions getInstance(final String description) {
for (final SelectOptions selectOptions : SelectOptions.values()) {
if (selectOptions.description == description) {
return selectOptions;
}
}
throw new IllegalArgumentException("SelectOptions could not be determined with description [" + description + "]");
}
/**
* Simple Getter.
*
* #return the id
*/
public int getId() {
return this.id;
}
/**
* Simple Setter.
*
* #param id the id to set
*/
public void setId(final int id) {
this.id = id;
}
/**
* Simple Getter.
*
* #return the description
*/
public String getDescription() {
return this.description;
}
/**
* Simple Setter.
*
* #param description the description to set
*/
public void setDescription(final String description) {
this.description = description;
}
}
Controller
public class SpringController implements SpringControllerInterface {
/**
* /WEB-INF/jsp/myJSP.jsp.
*/
private static final String PAGE = "/WEB-INF/jsp/myJSP.jsp";
/**
* {#inheritDoc}
*/
#Override
public ModelAndView load(final Model model) {
final ModelAndView mav = new ModelAndView(PAGE);
final List<SelectOptions> availableOptions = this.getAvailableOptions();
mav.addObject("availableOptions", availableOptions);
return mav;
}
/**
* {#inheritDoc}
*/
#Override
public ModelAndView save(final Model model) {
final ModelAndView mav = new ModelAndView(PAGE);
// TODO
return mav;
}
/**
* {#inheritDoc}
*/
#Override
public Model getModel() {
return new ModelImpl();
}
/**
* #return a list of available options
*/
public List<SelectOptions> getAvailableOptions() {
final List<SelectOptions> availableOptions = Lists.newArrayList();
availableOptions.add(SelectOptions.OPTION_1);
availableOptions.add(SelectOptions.OPTION_7);
availableOptions.add(SelectOptions.OPTION_8);
return availableOptions;
}
}
Model
public class ModelImpl implements Model {
private SelectOptions selectOptions;
/**
* Simple Getter.
*
* #return the selectOptions
*/
#Override
public SelectOptions getSelectOptions() {
return this.selectOptions;
}
/**
* Simple Setter.
*
* #param selectOptions the selectOptions to set
*/
#Override
public void setSelectOptions(final SelectOptions selectOptions) {
this.selectOptions = selectOptions;
}
}
If you created a spring controller and you want to pass an enum to your jsp page, you can do it like this:
Enum example:
public enum Coin {
HEADS("Heads", "heads"),
TAILS("Tails", "tails");
private final String fullName;
private final String shortName;
private Coin(String fullName, String shortName) {
this.fullName = fullName;
this.shortName = shortName;
}
public String getFullName() {
return fullName;
}
public String getShortName() {
return shortName;
}
}
Passing this enum to your model:
model.addObject("coins", Coin.values());
Using it in your jsp page with form:
<form:select path="selection">
<form:options items="${coins}" itemValue="shortName" itemLabel="fullName" />
</form:select>
It looks like the solution to this problem was that I was using the attribute "path" in the <spring-form:options> tag. It should have been "items", not "path".
the corrected JSP fragment:
<spring-form:select path="selectOptions">
<spring-form:option value="" label="*** Select Option ***" />
<spring-form:options items="${availableOptions}" />
</spring-form:select>
You do not even need to use items attribute if you are using <spring-form:options> tag.
The options tag:
Renders a list of HTML 'option' tags. Sets 'selected' as appropriate based on bound value.
References Spring form tld.
So for your need I guess falling back to JSTL core with <spring-form:option/> will suffice.