POJO dataset nested rendering - birt

My POJO Datasource basically contains following structure.
// Company.java
public class Company implements Serializable {
private static final long serialVersionUID = 3130918429913376956L;
private String name;
private String address;
private String contactPerson;
private String mobile;
private String fax;
private String bankDetails;
private String email;
private List<Employee> emps;
//getter and setter.
}
// Employee.java
public class Employee implements Serializable{
/**
*
*/
private static final long serialVersionUID = -4473328670062370497L;
private String name;
private int age;
private String designation;
//getter and setter
}
My scenario is like following
One PDF report may have more that one Company (ie List< Company >)
In case of more than one Company, it should start at new page.
If Employee list goes to next page then it should repeat Header on the next page.
Layout -
Layout xml source
Output Page 1
Page 2
There are two issues with this design
Employee Name header is getting repeated for every employee.
Company Header (Comp Name -> Company A ) should be rendered only once.
Can anyone suggest me correct approach ? Thanks in advance.

Move the 'company name' to the Header row and set the header property to not repeating on new pages. Move the 'Employee name' out of the grouping with 'Employee', so up to the level where 'company name' is now.
I think you know everything to solve this, you just have to fiddle with the groupings a bit.

Related

Fortify Cross-Site Scripting : Content Sniffing fix for DTO response

So I'm trying to fix Fortify Vulnerability Issue for content-sniffing, and this needs to use StringEscapeUtils.escapeHtml4 for all attributes of the DTO.
My problem is that the DTO is not a simple object, but rather having nested objects as its attributes:
Root DTO:
public class ServiceOrderListDTO implements Serializable {
private String count;
private String next;
private String previous;
private List<ServiceOrderDetailDTO> results;
}
public class ServiceOrderDetailDTO implements Serializable {
private static final long serialVersionUID = -819641011600662396L;
#JsonProperty("order_code")
private String orderCode;
#JsonProperty("service_number")
private String serviceNumber;
#JsonProperty("customer_name")
private String customerName;
#JsonProperty("customer_brn")
private String customerBrn;
private CustomerDTO[] customer;
#JsonProperty("order_details")
private OrderDetailsDTO orderDetails;
#JsonProperty("site_a_address")
private String siteAAddress;
#JsonProperty("site_b_address")
private String siteBAddress;
#JsonProperty("dff_service_order_id")
private String dffServiceOrderID;
#JsonProperty("dff_response")
private DffResponse dffResponse;
private MilestonesDTO milestones;
private AppointmentsDTO appointments;
}
So I need to Iterate through all the child objects and apply the escapehtml4 function one by one.
However I got feedback that this may lead to performance issue. Is there a way that the escapeHtml4 be applied in the DTO as a whole?
I've been going through SO also but no viable solution so far.
Cross-Site Scripting/Content Sniffing vulnerability detected through static scan for API while returning response

Spring redirect simple rest POST with body (json) on another port

I have 2 spring rest applications.
When I send data to the first one,
private Long id;
private String name;
private String surname;
private String productName;
private Double productValue;
First I create a client entry in DB with the fields:
private Long id;
private String name;
private String surname;
and than
I would like to make a redirect post to another port, another application
handling product data with body including the two fields:
private String productName;
private Double productValue;
private Long clientId;
to create a product entry in the db
after creating product, I would like to redirect back to the first app and show the saved client.
The question is, how should I build my Controller?
Do I have to use ModelAndView? - this is only a backend rest, without any front (run from postman :)
You may like to do this way first autowire RestTemplate and then use it to call another api -
#RestController
public class ProductResource {
#Autowired
RestTemplate restTemplate;
#Autowired
private ProductRepository repository;
#PostMapping
public ResponseEntity<Product> saveProduct(#RequestBody Product product) {
Product productSavedAtClient = repository.save(product);
Product savedProduct = restTemplate.postForObject("http://some.other.app/product", productSavedAtClient, Product.class);
return ResponseEntity.ok().body(savedProduct);
}
}

Spring JPA bidirectional relation on multiple nested entities

I know there has been multiple questions on bidirectional relations using spring jpa in the past but my case is a little bit different because i am using 3 entities with 2 relationships to implement a medical system
I have 3 entities : doctor/patient/appointment
here is the code for the 3 entities
please note all setters , getters and constructors implemented but ommited here for clarity
Patient class
#Entity
public class resPatient {
#Id
#GeneratedValue( strategy= GenerationType.IDENTITY )
private long code;
private String name;
private String gender;
private String email;
private String mobile;
private int age;
private String notes;
#OneToMany(mappedBy = "patient")
List<resPackageMembership> memberships;
#OneToMany(mappedBy = "patient")
List<resAppointment> appointments;
#OneToMany(fetch = FetchType.LAZY,mappedBy = "patient")
List<resMedImage> medImages;
Doctor class
#Entity
public class resDoctor {
#Id
#GeneratedValue( strategy= GenerationType.IDENTITY )
private long code;
private String name;
private String mobile;
private String email;
private String gender;
private int age;
private String speciality;
#OneToMany(mappedBy = "doctor")
List<resAppointment> appointments;
Appointment class
#Entity
public class resAppointment {
#Id
#GeneratedValue( strategy= GenerationType.IDENTITY )
private long code;
private String speciality;
#Basic
#Temporal(TemporalType.TIMESTAMP)
private Date dateCreated;
#Basic
#Temporal(TemporalType.TIMESTAMP)
private Date dateToVisit;
private String status;
private String notes;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "doctorCode")
private resDoctor doctor;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "patientCode")
private resPatient patient;
the way my medical system should work is that when i get a patient using my restful controller i want all the patient data including his appointments but this leads to an infinite loop as the appointment has the doctor which also has appointments and so on.
i cannot user #JSONIGNORE as there are 2 relationships i want to get the patient with his appointments which should have the doctor without the appointments array and should not have any patient data as i already am in the patient object
As a general best-practice, it's recommended to separate the entities from the data transfer objects used for the rest controllers. With DTO's in place, you have more control on which data to include and serialize within them to avoid the circlular references.
If you like check out https://bootify.io, it generates the DTOs from your database schema, but the custom endpoint you still need to define/build.
I develop an annotation processor called beanknife recently, it support generate DTO from any class. You need config by annotation. But you don't need change the original class. This library support configuring on a separate class. Of course you can choose which property you want and which you not need. And you can add new property by the static method in the config class. For your question:
// this will generate a DTO class named "resPatientView".
// You can change this name using genName attribute.
#ViewOf(value=resPatient.class, includePattern = ".*")
public class PatientViewConfigure {
// here tell the processor to automatically convert the property appointments from List<resAppointment> to List<resAppointmentWithoutPatient>.
// resAppointmentWithoutPatient is the generated class configured at the following.
// Note, although at this moment it not exists and your idea think it is an error.
// this code really can be compiled, and after compiled, all will ok.
#OverrideViewProperty("appointments")
private List<resAppointmentWithoutPatient> appointments;
}
// here generated a class named resAppointmentWithoutPatient whick has all properties of resAppointment except patient
#ViewOf(value=resAppointment.class, genName="resAppointmentWithoutPatient", includePattern = ".*", excludes={"patient"})
public class AppointmentWithoutPatientViewConfigure {
// the doctor property will be converted to its dto version which defined by the configure class DoctorWithoutAppointmentsViewConfigure.
#OverrideViewProperty("doctor")
private resDoctorWithoutAppointments doctor;
}
// here we generate a class which has all properties of resDoctor except appointments
#ViewOf(value=resDoctor.class, genName="resDoctorWithoutAppointments", includePattern = ".*", excludes={"appointments"})
public class DoctorWithoutAppointmentsViewConfigure {}
// in you rest controller. return the dto instead of the entities.
resPatient patient = ...
resPatientView dto = resPatientView.read(patient);
List<resPatient> patients = ...
List<resPatientView> dto = resPatientView.read(patients);
At the end, the class resPatientView will has the same shap with resPatient except its appointments not having patient property and its doctor property is replaced with a version without appointments property.
Here are more examples.
The version 1.10 is ready. Will fix some bug and support the configure bean to be managed by spring.

Spring boot using Autowire Cofiguration property class in Entity class

I have to use some set data member class in Spring entity class
Current Entity class
Entity(name="users")
public class Users{
#Id
#GeneratedValue
#Column(name=ID")
private long Id;
#Column(name=NAME")
private String name;
#Column(name=AGE")
private String age;
#Column(name=PIN")
private String pin;
public Users(String name, String age, String pin)
{
this.name = name;
this.age = age;
this.pin = pin;
}
}
Now I need to add a new Member which is unique to that place
areaId, we run sperate application per each area so this will be passed from command line arguments or config properties during application starts.
My properties class looks like below
#Component
#ConfigurationProperties("user.info")
public class UserProperties{
public String areaId;
public String getAreaID(){return this.areaId;}
public void setAreaID(String areaId){ this.areaId = areaId;}
}
users:
info:
areaId:124
I have to store this and initializes also during Users object constructing, here I am trying to make simple
Entity(name="users")
public class Users{
#Id
#GeneratedValue
#Column(name=ID")
private long Id;
#Column(name=NAME")
private String name;
#Column(name=AGE")
private String age;
#Column(name=PIN")
private String pin;
#Column(name=AREAID")
private String areaId;
public Users(String name, String age, String pin)
{
this.name = name;
this.age = age;
this.pin = pin;
this.areaId = ""//?? how to get area id directly ?
}
}
I can not change the constructor of Users because it demands changes in the other application which are using this lib
Want to Autowire a users properties class inside Entity class(but this is not suggestable as read in some articles )
What would be the best way to initialize that default kind of variable?
It seems that your property is something static.
Then get it from a static way at start.
There's several ways to get command line value at start directly or in a static block:
static {
(your code here)
}
You'll can put #Column on a getter on this property after that.

How to add properties to the relationship in Spring data neo4j when we use createRelationshipBetween

For example I want to make relationship between User A and User B and they have RelationshipEntity named MakeFriend, I am used code below, but I am also want to set in relation entity some property values like role = 10.........
userRepository.createRelationshipBetween(startUser, endUser, MakeFriend.class, RelTypes.FRIEND.name());
#RelationshipEntity
public class MakeFriend {
#GraphId
private Long id;
private String role;
#StartNode
private UserEntity startUser;
#EndNode
private UserEntity endUser
#NodeEntity
public class UserEntity implements Serializable {
private static final long serialVersionUID = 1L;
public static final String FRIEND = "FRIEND";
public static final String JOYNED = "JOYNED";
#GraphId
private Long id;
#Indexed(unique = true)
private Long userId;
private String email;
You could could add the following to your UserEntity class:
#RelatedToVia(type = RelTypes.FRIEND, direction = Direction.BOTH)
private MakeFriend friend;
friend.setRole("yourRole");
Another way to do it, when you're using the advanced mapping mode, is using one of the NodeBacked.relateTo() methods. Then add the property to the returned Relationship.
And a third way, it to use the Neo4jTemplate.createRelationshipBetween() method and provide your properties (e.g. role) as the final argument.

Resources