How abstract common classes? - java

Am developing webapplication with JSF and Hibernate, have Entity, Entity data access & JSF managed bean classes in following pattern and same repeats in all the classes. Since all the classes have the same pattern, I would like to make it as abstract class.
Entity Class
public class MyEntity {
-----
-----
}
Data Access class
public class MyEntityDAO extends AbstractDAO<MyEntity> {
MyEnitityDAO(){
-------
}
}
JSF Managed bean
public class MyBean implements Serializable {
private static final long serialVersionUID = 1L;
private MyEntity current;
private MyEntityDAO dao;
private DataModel<MyEntity> items = null;
public MyBean() {
// TODO Auto-generated constructor stub
}
public MyEntity getCurrent() {
return current;
}
public void setCurrent(MyEntity current) {
this.current = current;
}
public MyEntityDAO getDao() {
if (dao == null) {
dao = new MyEntityDAO();
}
return dao;
}
public DataModel<MyEntity> getItems() {
return items;
}
public List<MyEntity> getMyEntityList() {
return getDao().findAll();
}
public MyEntity getMyEntity(int id) {
return getDao().findById(id);
}
private void reSetDataModel() {
items = null;
}
private void reSetCurrent() {
setCurrent(null);
}
public void prepareCreate() {
current = new MyEntity();
}
public void create() {
// Save the entity
}
public void edit() {
// Update the entity
}
public void delete() {
// Remove the entity
}
}
How to make the abstract class out of above pattern?

Type the word abstract between public and class

Related

how to implement public AbstractEntryProcessor(boolean applyOnBackup){} in 5.x.x for the backup in Hazelcast

Help me in the following code and how to used the backup on the Hazelcast
migration of the hazelcast 3.x.x to 5.x.x
package com.hazelcast.map;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.HazelcastInstanceAware;
import com.hazelcast.nio.serialization.impl.BinaryInterface;
import java.util.Map;
// Interface AbstractEntryProcessor
#BinaryInterface
public abstract class AbstractEntryProcessor<K,V> implements EntryProcessor<K,V> {
private final EntryBackupProcessor<K,V> entryBackupProcessor;
// Non Parameterize Constructor
public AbstractEntryProcessor() {
this(true);
}
// Parameterize Constructor AbstractEntryProcessor
public AbstractEntryProcessor(boolean applyOnBackup) {
if (applyOnBackup) {
entryBackupProcessor = new EntryBackupProcessorImpl();
} else {
entryBackupProcessor = null;
}
}
//EntryBackupProcessor
#Override
public final EntryBackupProcessor getBackupProcessor() {
return entryBackupProcessor;
}
// class EntryBackupProcessorImpl
private class EntryBackupProcessorImpl implements EntryBackupProcessor<k,V>, HazelcastInstanceAware {
// generated for EntryBackupProcessorImpl which doesn't implement HazelcastInstanceAware
static final long serialVersionUID = -5081502753526394129L;
#Override
public void processBackup(Map.Entry<K,V> entry) {
process(entry);
}
#Override
public void setHazelcastInstance(HazelcastInstance hazelcastInstance) {
final AbstractEntryProcessor<k,V> outer = AbstractEntryProcessor.this;
if (outer instanceof HazelcastInstanceAware) {
((HazelcastInstanceAware) outer).setHazelcastInstance(hazelcastInstance);
}
}
}
}
How to used the backup methods in 5.x.x versons of series
how to used the backup in the above question ?
This should work:
public abstract class AbstractEntryProcessor implements EntryProcessor, HazelcastInstanceAware {
protected transient HazelcastInstance hazelcastInstance;
private final boolean applyOnBackup;
// Non Parameterize Constructor
public AbstractEntryProcessor() {
this(true);
}
// Parameterize Constructor AbstractEntryProcessor
public AbstractEntryProcessor(boolean applyOnBackup) {
this.applyOnBackup = applyOnBackup;
}
//EntryBackupProcessor
#Override
public final EntryProcessor getBackupProcessor() {
if (!applyOnBackup || this instanceof ReadOnly) {
return null;
}
return this;
}
#Override
public void setHazelcastInstance(HazelcastInstance hazelcastInstance) {
this.hazelcastInstance = hazelcastInstance;
}
}

Spring Boot Abstract Singleton Service problem

Hi everyone this is my simple project code block
This service is renewing by sending a request once a day.
public class SingletonService {
private static final SingletonService INSTANCE = new SingletonService();
public static final int TIMEOUT_SEC = 86400 ;//SECONDS every day ONE REQUEST remote service
private static final Object lock = new Object();
private LocalDateTime queryDate;//Time
private EmployeeRepository employeeRepository;//My Remote Employee Repository
private List<Employee> list = new CopyOnWriteArrayList<>();
SingletonService() {//Singleton Design Pattern
}
public static SingletonService getInstance() {
return INSTANCE;
}
private boolean isTimeout() {//this methods check date
LocalDateTime execDate = LocalDateTime.now();
if (queryDate == null) {
return true;
}
LocalDateTime expireDate = queryDate.plusSeconds(TIMEOUT_SEC);
return expireDate.isBefore(execDate);
}
public synchronized void reload() {//this methods call repository employee list
queryDate = LocalDateTime.now();
list = employeeRepository.findAll();
}
public void initQuery() {//this methods check expire date and list size
synchronized(lock) {
if (isTimeout() || list.size() <= 0) {
reload();
}
}
}
public Integer countLatestRanking() {
return list.size();
}
public void setEmployeeRepository(EmployeeRepository employeeRepository) {
this.employeeRepository = employeeRepository;
}
public List<Employee> getList() {
return this.list;
}
public void setList(List<Employee> list) {
this.list = list;
}
}
My SingletonInitService
#Component
public class SingletonInitService {
#Autowired
private EmployeeRepository employeeRepository;
#PostConstruct
public void init() {
SingletonService.INSTANCE.setEmployeeRepository(employeeRepository);
}
public void onContextRefreshedEvent() {
SingletonService.INSTANCE.initQuery();
}
public List<Employee> getEmployees(){
return SingletonService.INSTANCE.getList();
}
}
My EmployeeService
#Service
public class EmployeeService {
#Autowired
private SingletonInitService singletonInitService;
public List<Employee> getEmployees(){
singletonInitService.onContextRefreshedEvent();
return singletonInitService.getEmployees();
}
}
My question is how can I write SingletonService abtract because I have too many repositories and I don't want to write this code over and over again (Please don't say why you didn't use the scheduler because it's not good to use job all the time)

Java - Generic for Payment processing with Strategy pattern

I am trying to implement Strategy pattern approach for payment processing in my Spring webflux based application.
My application supports multiple payment method like, Card Payment, Cash Payment, ...
Also, we have to support Square & Stripe for Card payment.
Model class,
// Model interface
public interface PaymentModel {
}
// Base model with attributes needed for all payment types
public class BaseModel implements PaymentModel {
private Float amount;
private Integer userId;
}
public class SquareCardModel extends BaseModel {
private String merchantId;
private String device;
private String orderId;
}
public class StripeCardModel extends BaseModel {
private String merchantId;
private String orderId;
}
public class CashModel extends BaseModel {
private String name;
private String orderId;
}
Service Class,
#Service
public interface PaymentService<T extends PaymentModel> {
Mono<ServerResponse> pay(T model);
String method();
}
#Service
public class CashPaymentService implements PaymentService<CashModel> {
private static final String PAYMENT_METHOD = "cash";
#Override
public Mono<ServerResponse> pay(CashModel model) {
// TODO Auto-generated method stub
return null;
}
#Override
public String method() {
return PAYMENT_METHOD;
}
}
#Service
public class SquarePaymentService implements PaymentService<SquareCardModel> {
private static final String PAYMENT_METHOD = "cash";
#Override
public Mono<ServerResponse> pay(SquareCardModel model) {
// TODO Auto-generated method stub
return null;
}
#Override
public String method() {
return PAYMENT_METHOD;
}
}
#Service
public class StripePaymentService implements PaymentService<StripeCardModel> {
private static final String PAYMENT_METHOD = "cash";
#Override
public Mono<ServerResponse> pay(SquareCardModel model) {
// TODO Auto-generated method stub
return null;
}
#Override
public String method() {
return PAYMENT_METHOD;
}
}
Factory Class,
#Service
public class PaymentFactory<T> {
private final List<PaymentService<? extends PaymentModel>> paymentServices;
#Autowired
public PaymentFactory(List<PaymentService<? extends PaymentModel>> paymentServices) {
this.paymentServices = paymentServices;
}
public PaymentService<? extends PaymentModel> retrievePaymentService(final String paymentMethod) {
Optional<PaymentService<? extends PaymentModel>> paymentService = paymentServices.stream()
.filter(service -> service.method().equals(paymentMethod)).findFirst();
if (paymentService.isEmpty()) {
throw new IllegalArgumentException("Unsupported Payment method ");
}
return paymentService.get();
}
}
User choose the payment method and the call comes to the backend,
#Transactional
public Mono<ServerResponse> payBilling(ServerRequest request) {
return request.bodyToMono(PaymentDto.class).flatMap(paymentReq -> {
if (paymentReq.getPaymentType().equals("CC")) { // For Card
return processCardPayment(usr, paymentReq);
} else {
return badRequest().bodyValue("Not supported yet !");
}
});
}
private Mono<? extends ServerResponse> processCardPayment(
PaymentDto paymentReq) {
PaymentService<PaymentModel> paymentService = (PaymentService<PaymentModel>) paymentFactory
.retrievePaymentService(paymentReq.getPaymentType());
PaymentModel paymentModel = buildPaymentModel((String) paymentReq.getPaymentType(), paymentReq,
jsonMap);
return paymentService.pay(paymentModel);
}
private PaymentModel buildPaymentModel(final String paymentMethod, final PaymentDto paymentReq,
if (paymentMethod.equals("squarePayment")) {
SquareCardModel model = new SquareCardModel();
model.setAmount(paymentReq.getTotal());
model.setMerchantId(paymentReq.getMerchantid());
model.setOrderId(orderId);
return model;
}
return null;
}
Questions:
Not sure if I have implemented generics properly with the strategy pattern.
Also, I dont like type casting here. (PaymentService). is there any better approach?
Why do I still need to use if for creating different model.
if (paymentMethod.equals("squarePayment")) {
PaymentService<PaymentModel> paymentService = (PaymentService<PaymentModel>) paymentFactory
.retrievePaymentService(paymentReq.getPaymentType());
PaymentModel paymentModel = buildPaymentModel((String) paymentReq.getPaymentType(), paymentReq,
jsonMap);
return paymentService.pay(paymentModel);
Here's a simplified version of your code which I think maintains what you need to do, from a type perspective:
import java.util.Optional;
public class App {
public interface PaymentModel { }
public static class CashModel implements PaymentModel { }
public interface PaymentService<T extends PaymentModel> {
void pay(T model);
void pay2(PaymentModel model);
}
public static class PaymentFactory {
public PaymentService<PaymentModel> retrievePaymentService(final String paymentMethod) {
Optional<PaymentService<PaymentModel>> paymentService = null;
return paymentService.get();
}
public PaymentService<? extends PaymentModel> retrievePaymentService2(final String paymentMethod) {
Optional<PaymentService<PaymentModel>> paymentService = null;
return paymentService.get();
}
}
public static void main(String... args) throws NoSuchFieldException, IllegalAccessException {
PaymentFactory paymentFactory = null;
PaymentService<PaymentModel> paymentService = paymentFactory
.retrievePaymentService("foo");
paymentService.pay(new CashModel());
PaymentService<? extends PaymentModel> paymentService2 = paymentFactory
.retrievePaymentService2("foo");
paymentService2.pay(new CashModel()); // error
paymentService2.pay2(new CashModel()); // ok
}
}
Look at the difference between retrievePaymentService and retrievePaymentService2.
retrievePaymentService returns PaymentService<PaymentModel> which says that it is a payment service which works on any PaymentModel implementation.
retrievePaymentService2 returns PaymentService<? extends PaymentModel> which says that it is a payment service which works on some specific, unknown PaymentModel implementation.
As you have already made sure that your PaymentModel type matches the PaymentService you are getting from the factory, the first form is what you want.
A better design might try to not have two parallel class hierarchies which need to be matched up carefully at runtime.
Also, processCardPayment seems as though it should handle all PaymentModels?

DAO pattern with realm

How can DAO be used with realm? Because when in my activity I try to set members of my model class I get an exception :
java.lang.IllegalStateException: Changing Realm data can only be done from inside a transaction.
I know that using realm.executeTransaction fixes the issue, but the code in my activity is no more database-agnostic because it will countain code that is specific to low level database communication. So later if I want to change database, the refactoring will cost a lot of time and work... Besides, I will have to handle in all my activities a reference to Realm.getDefaultInstance();
Here is sample of code of my activity
protected void onCreate(Bundle savedInstanceState)
{
mBook = mBookDaoImpl.getBookById(bookId);
}
// Later in the code
private void saveBook(String name)
{
mBook.setName(name);
}
Here is my model class
public class Book extends RealmObject
{
#Required
#PrimaryKey
private String id;
private String name;
public Book() {
}
public Book(String id, String name) {
this.id = id;
this.name = name;
}
// getter setter methods
}
Here is my DAO interface :
public interface BookDao
{
List<Book> getAllBooks();
Book getBookByIsbn(int isbn);
void saveBook(Book book);
void deleteBook(Book book);
}
And finally is my implementation :
public class BookDaoImpl implements BookDao
{
private static BookDaoImpl INSTANCE = null;
private Realm mRealm;
private BookDaoImpl()
{
mRealm = Realm.getDefaultInstance();
}
public static BookDaoImpl getInstance()
{
if (INSTANCE == null)
INSTANCE = new BookDaoImpl();
return INSTANCE;
}
#Override
public List<Book> getAllBooks()
{
return mRealm.where(Book.class).findAll();
}
#Override
public Book getBookById(String id)
{
return mRealm.where(Book.class).equalTo("id", id).findFirst();
}
#Override
public void saveBook(final Book book)
{
mRealm.executeTransaction(new Realm.Transaction()
{
#Override
public void execute(Realm realm)
{
if (book.getId() == null)
book.setId(UUID.randomUUID().toString());
realm.copyToRealmOrUpdate(book);
}
});
}
#Override
public void deleteBook(final Book book)
{
mRealm.executeTransaction(new Realm.Transaction()
{
#Override
public void execute(Realm realm)
{
mRealm.where(Counter.class).equalTo("id", book.getId())
.findFirst()
.deleteFromRealm();
}
});
}
}
Realm's getInstance() method returns a thread-local, reference counted instance which must be paired with a close() call, so your DAO implementation probably won't suit what you expect.
If you use my library Realm-Monarchy which I created specifically for making it easier to "abstract Realm away", then you can implement your DAO like this:
public class BookDaoImpl implements BookDao
{
private static BookDaoImpl INSTANCE = null;
private Monarchy monarchy;
private BookDaoImpl(Monarchy monarchy)
{
this.monarchy = monarchy;
}
public static BookDaoImpl getInstance(Monarchy monarchy)
{
if (INSTANCE == null) {
synchronized(BookDaoImpl.class) {
if(INSTANCE == null) {
INSTANCE = new BookDaoImpl(monarchy);
}
}
}
return INSTANCE;
}
#Override
public List<Book> getAllBooks()
{
return monarchy.fetchAllCopiedSync((realm) -> realm.where(Book.class));
}
#Override
public Book getBookById(final String id)
{
List<Book> books = monarchy.fetchAllCopiedSync((realm) -> realm.where(Book.class).equalTo("id", id));
if(books.isEmpty()) {
return null;
} else {
return books.get(0);
}
}
#Override
public void saveBook(final Book book)
{
monarchy.runTransactionSync((realm) -> {
if (book.getId() == null)
book.setId(UUID.randomUUID().toString());
realm.insertOrUpdate(book);
});
}
#Override
public void deleteBook(final Book book)
{
monarchy.runTransactionSync((realm) -> {
realm.where(Counter.class).equalTo("id", book.getId())
.findFirst()
.deleteFromRealm();
});
}
}
P.S.: you're throwing away a lot of power/functionality if you return List<T> synchronously, instead of an observable like LiveData<List<T>> (or originally, RealmResults<T>).

Inheritence using java generics not working as expected

I am trying to use inheritence and generics to create my application, but it doesn't seem to work the way I expect it to. I'll show you what I mean (TL;DR at the bottom):
public interface IModel extends Serializable {
public int save();
public void update();
public void delete();
}
// <T> is a JPA annotated entity/class
#SuppressWarnings("serial")
public abstract class Model<T> implements IModel {
private final Repository<T> _repository;
protected T _entity;
public Model(T entity, Repository<T> repository) {
this._entity = entity;
this._repository = repository;
}
public int save() {
return _repository.save(_entity);
}
...
}
This is implemented in for example my AccountModel, which is a Model with generic Account (which is a JPA entity) and which implements IAccount.
public class AccountModel extends Model<Account> implements IAccount {
private static final AccountRepository REPOSITORY = new AccountRepository();
public AccountModel(Account entity) {
super(entity, REPOSITORY);
}
// Method implementations...
}
My generic Repository looks like this:
public abstract class Repository<T> implements Serializable {
private static SessionFactory SESSION_FACTORY;
private final Class<T> _repositoryClass;
private static boolean _initiated = false;
public Repository(Class<T> repositoryClass) {
if (!Repository._initiated)
setup();
this._repositoryClass = repositoryClass;
}
private void setup() {
// logics
Repository._initiated = true;
}
public final Model<T> getById(int id) {
Session session = SESSION_FACTORY.openSession();
try {
session.beginTransaction();
T t = session.get(_repositoryClass, id);
return new Model<T>(t, this); // As suggested by #Vlad
}
finally {
session.close();
}
}
}
The account implementation of this abstract Repository is:
public class AccountRepository extends Repository<Account> {
public AccountRepository() {
super(Account.class);
}
public Model<Account> getByEmail(String emailAddress) {...}
}
So far so good, this is all working as expected. But I cannot use a Model<T> as a TModel.
TL;DR
I would like use the following line of code:
AccountModel account = new AccountRepository().getById(1);
Since AccountModel inherits Model<Account> and new AccountRepository().getById() always returns Model<Account> I expect this to work, but it doesn't.
What am I missing?

Categories

Resources