apache wicket - column link inside DataTable on table change (lets say filter and getting 0 rows) the opened link page fail - wicket

scenario : I am using data table with columns
one of the columns is link .
on run time I calculate the link created
the problem start when:
1. opennig table page P1
2. I clicked on link open in new tab
2.new tab is created with this URL
mit:8080/backoffice/?4-1.ILinkListener-MainPanelComponentWrapper-MainPanelComponent-table-gridForm-grid-body-rows-3-cells-2-cell-link
which is a component on P1 ,this tab generate P2.
changing P1 ,filtering on ajax and the table is empty so table-gridForm has no data
refreshing P2
getting exception
org.apache.wicket.WicketRuntimeException: Component 'MainPanelComponentWrapper:MainPanelComponent:table:gridForm:grid:body:rows:1:cells:2:cell:link' has been removed from page.
i need to create a redirected link that the new page woul be linked to .
how can i achive it ?
public class LinkPropertyColumn<T extends IEntity> extends BOPropertyColumn<T, String> implements IBOExportableColumn<T, String, Object> {
private static final long serialVersionUID = 1L;
private String headerTilte;
private GridViewType navigateTo;
private String routingByProperty;
private String entityId;
private String navigateToDynamicFunction;
private Map<String, String> filterByMap;
protected BOLinkPanel<T> linkPanel ;
public LinkPropertyColumn(String displayModel, String propertyToSortBy, String propertyExpression, String entityId,
String routingByProperty, String headerTilte, String navigateToDynamic) {
super(Model.of(displayModel), propertyToSortBy, propertyExpression);
this.headerTilte = headerTilte;
this.entityId = entityId;
this.navigateToDynamicFunction = navigateToDynamic;
this.routingByProperty = routingByProperty;
}
#Override
public Component getHeader(String componentId) {
return new Label(componentId, headerTilte);
}
#Override
public void populateItem(Item<ICellPopulator<T>> item, String componentId, final IModel<T> rowModel) {
linkPanel = new BOLinkPanel<T>(componentId, rowModel, getPropertyExpression()) {
private static final long serialVersionUID = 1L;
#Override
void onLinkClicked() {
LinkPropertyColumn.this.onLinkClicked(rowModel);
}
};
item.add(linkPanel);
}
public void onLinkClicked(IModel<T> rowModel) {
doing stuff...
params.add(HomePage.ENTITY_ID, idProperty);
final Object routingProperty = routingByProperty == null ? idProperty : BeanUtils.getProperty(object, routingByProperty);
params.set(HomePage.ROUTING_PROPERTY, routingProperty);
HomePage homePage = new HomePage(params);
final RequestCycle requestCycle = RequestCycle.get();
requestCycle.setResponsePage(homePage);
}
}
}
and :
public abstract class BOLinkPanel<T> extends Panel {
private static final long serialVersionUID = 1L;
/**
* #param id
*/
public BOLinkPanel(String id, IModel<T> model, String propertyExpression) {
super(id);
AbstractLink link = getLink();
link.add(new Label("caption", new PropertyModel<String>(model.getObject(), propertyExpression)));
add(link);
}
protected AbstractLink getLink() {
Link<Void> link = new AjaxFallbackLink<Void>("link") {
private static final long serialVersionUID = 1L;
#Override
public void onClick(AjaxRequestTarget target) {
// TODO Auto-generated method stub
BOLinkPanel.this.onLinkClicked();
}
// #Override
// public void onClick() {
// BOLinkPanel.this.onLinkClicked();
//
// }
};
return link;
}
abstract void onLinkClicked();
}

i did :
requestCycle.setResponsePage(HomePage.class, params);

Related

MongoRepository Save method does not insert in database

I have created a SpringBoot project with Jhipster. The database I am using is MongoDB.
In the application-dev.yml I have the following configuration:
data:
mongodb:
uri: mongodb://<user>:<pass>#<ip>:<port>
database: gateway
The user, password, ip Address, and port, in my application-dev are real values.
The DatabaseConfiguration.java is:
#Configuration
#EnableMongoRepositories("es.second.cdti.repository")
#Profile("!" + JHipsterConstants.SPRING_PROFILE_CLOUD)
#Import(value = MongoAutoConfiguration.class)
#EnableMongoAuditing(auditorAwareRef = "springSecurityAuditorAware")
public class DatabaseConfiguration {
private final Logger log = LoggerFactory.getLogger(DatabaseConfiguration.class);
#Bean
public ValidatingMongoEventListener validatingMongoEventListener() {
return new ValidatingMongoEventListener(validator());
}
#Bean
public LocalValidatorFactoryBean validator() {
return new LocalValidatorFactoryBean();
}
#Bean
public MongoCustomConversions customConversions() {
List<Converter<?, ?>> converters = new ArrayList<>();
converters.add(DateToZonedDateTimeConverter.INSTANCE);
converters.add(ZonedDateTimeToDateConverter.INSTANCE);
return new MongoCustomConversions(converters);
}
#Bean
public Mongobee mongobee(MongoClient mongoClient, MongoTemplate mongoTemplate, MongoProperties mongoProperties) {
log.debug("Configuring Mongobee");
Mongobee mongobee = new Mongobee(mongoClient);
mongobee.setDbName(mongoProperties.getMongoClientDatabase());
mongobee.setMongoTemplate(mongoTemplate);
// package to scan for migrations
mongobee.setChangeLogsScanPackage("es.second.cdti.config.dbmigrations");
mongobee.setEnabled(true);
return mongobee;
}}
The CloudDatabaseConfiguration is:
#Configuration
#EnableMongoRepositories("es.second.cdti.repository")
#Profile(JHipsterConstants.SPRING_PROFILE_CLOUD)
public class CloudDatabaseConfiguration extends AbstractCloudConfig {
private final Logger log = LoggerFactory.getLogger(CloudDatabaseConfiguration.class);
#Bean
public MongoDbFactory mongoFactory() {
return connectionFactory().mongoDbFactory();
}
#Bean
public LocalValidatorFactoryBean validator() {
return new LocalValidatorFactoryBean();
}
#Bean
public ValidatingMongoEventListener validatingMongoEventListener() {
return new ValidatingMongoEventListener(validator());
}
#Bean
public MongoCustomConversions customConversions() {
List<Converter<?, ?>> converterList = new ArrayList<>();
converterList.add(DateToZonedDateTimeConverter.INSTANCE);
converterList.add(ZonedDateTimeToDateConverter.INSTANCE);
converterList.add(DurationToLongConverter.INSTANCE);
return new MongoCustomConversions(converterList);
}
#Bean
public Mongobee mongobee(MongoDbFactory mongoDbFactory, MongoTemplate mongoTemplate, Cloud cloud) {
log.debug("Configuring Cloud Mongobee");
List<ServiceInfo> matchingServiceInfos = cloud.getServiceInfos(MongoDbFactory.class);
if (matchingServiceInfos.size() != 1) {
throw new CloudException("No unique service matching MongoDbFactory found. Expected 1, found "
+ matchingServiceInfos.size());
}
MongoServiceInfo info = (MongoServiceInfo) matchingServiceInfos.get(0);
Mongobee mongobee = new Mongobee(info.getUri());
mongobee.setDbName(mongoDbFactory.getDb().getName());
mongobee.setMongoTemplate(mongoTemplate);
// package to scan for migrations
mongobee.setChangeLogsScanPackage("es.second.cdti.config.dbmigrations");
mongobee.setEnabled(true);
return mongobee;
}
}
The cdtiApp.java is:
#SpringBootApplication
#EnableConfigurationProperties({ApplicationProperties.class})
public class CdtiApp implements InitializingBean{
private static final Logger log = LoggerFactory.getLogger(CdtiApp.class);
private final Environment env;
public CdtiApp(Environment env) {
this.env = env;
}
/**
* Initializes cdti.
* <p>
* Spring profiles can be configured with a program argument --spring.profiles.active=your-active-profile
* <p>
* You can find more information on how profiles work with JHipster on https://www.jhipster.tech/profiles/.
*/
#PostConstruct
public void initApplication() {
Collection<String> activeProfiles = Arrays.asList(env.getActiveProfiles());
if (activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT) && activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_PRODUCTION)) {
log.error("You have misconfigured your application! It should not run " +
"with both the 'dev' and 'prod' profiles at the same time.");
}
if (activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT) && activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_CLOUD)) {
log.error("You have misconfigured your application! It should not " +
"run with both the 'dev' and 'cloud' profiles at the same time.");
}
}
/**
* Main method, used to run the application.
*
* #param args the command line arguments.
*/
public static void main(String[] args) {
SpringApplication app = new SpringApplication(CdtiApp.class);
DefaultProfileUtil.addDefaultProfile(app);
Environment env = app.run(args).getEnvironment();
logApplicationStartup(env);
}
private static void logApplicationStartup(Environment env) {
String protocol = "http";
if (env.getProperty("server.ssl.key-store") != null) {
protocol = "https";
}
String serverPort = env.getProperty("server.port");
String contextPath = env.getProperty("server.servlet.context-path");
if (StringUtils.isBlank(contextPath)) {
contextPath = "/";
}
String hostAddress = "localhost";
try {
hostAddress = InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
log.warn("The host name could not be determined, using `localhost` as fallback");
}
log.info("\n----------------------------------------------------------\n\t" +
"Application '{}' is running! Access URLs:\n\t" +
"Local: \t\t{}://localhost:{}{}\n\t" +
"External: \t{}://{}:{}{}\n\t" +
"Profile(s): \t{}\n----------------------------------------------------------",
env.getProperty("spring.application.name"),
protocol,
serverPort,
contextPath,
protocol,
hostAddress,
serverPort,
contextPath,
env.getActiveProfiles());
String configServerStatus = env.getProperty("configserver.status");
if (configServerStatus == null) {
configServerStatus = "Not found or not setup for this application";
}
log.info("\n----------------------------------------------------------\n\t" +
"Config Server: \t{}\n----------------------------------------------------------", configServerStatus);
}
#Override
public void afterPropertiesSet() throws Exception {
// TODO Auto-generated method stub
}
}
The Vehicle entity:
#org.springframework.data.mongodb.core.mapping.Document(collection = "vehicle")
public class Vehicle implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private String id;
#NotNull
#Field("plate")
private String plate;
#NotNull
#Field("registrationDate")
private Instant registrationDate;
#NotNull
#Field("brand")
private String brand;
#NotNull
#Field("model")
private String model;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPlate() {
return plate;
}
public void setPlate(String plate) {
this.plate = plate;
}
public Instant getRegistrationDate() {
return registrationDate;
}
public void setRegistrationDate(Instant registrationDate) {
this.registrationDate = registrationDate;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
}
The VehicleDTO is:
public class VehicleDTO {
private String id;
private String plate;
private Instant registrationDate;
private String brand;
private String model;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPlate() {
return plate;
}
public void setPlate(String plate) {
this.plate = plate;
}
public Instant getRegistrationDate() {
return registrationDate;
}
public void setRegistrationDate(Instant registrationDate) {
this.registrationDate = registrationDate;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
}
The VehicleMapper is:
#Mapper(componentModel = "spring")
public interface VehicleMapper{
Vehicle toEntity(VehicleDTO source);
VehicleDTO toDto(Vehicle target);
}
The VehicleResource is:
#RestController
#RequestMapping("/api")
#CrossOrigin(origins = "*", methods = { RequestMethod.GET, RequestMethod.POST })
public class VehicleResource {
private final Logger log = LoggerFactory.getLogger(VehicleResource.class);
#Value("${jhipster.clientApp.name}")
private String applicationName;
#Autowired
private final VehicleService vehicleService;
public VehicleResource(VehicleService vehicleService) {
this.vehicleService = vehicleService;
}
#PostMapping("/vehicle")
#PreAuthorize("hasAuthority(\"" + AuthoritiesConstants.ADMIN + "\")")
public ResponseEntity<Vehicle> createVehicle(#Valid #RequestBody VehicleDTO vehicleDTO) throws URISyntaxException {
log.debug("REST request to save Vehicle : {}", vehicleDTO);
Vehicle newVehicle = vehicleService.createVehicle(vehicleDTO);
return ResponseEntity.created(new URI("/api/vehicle/" + newVehicle.getPlate()))
.headers(HeaderUtil.createAlert(applicationName, "vehicleManagement.created", newVehicle.getPlate()))
.body(newVehicle);
}
}
The VehicleService interface is:
public interface VehicleService {
Vehicle createVehicle(VehicleDTO vehicleDTO);
}
The VehicleServiceImpl is:
#Service
public class VehicleServiceImpl implements VehicleService{
#Autowired
private final VehicleRepository vehicleRepository;
#Autowired
private final VehicleMapper mapper;
public VehicleServiceImpl(VehicleRepository vehicleRepository, VehicleMapper mapper) {
this.vehicleRepository = vehicleRepository;
this.mapper = mapper;
}
private final Logger log = LoggerFactory.getLogger(VehicleServiceImpl.class);
#Override
public Vehicle createVehicle(VehicleDTO vehicleDTO) {
Vehicle vehicle = vehicleRepository.save(mapper.toEntity(vehicleDTO));
log.debug("Created Information for vehicle: {}", vehicle);
return vehicle;
}
}
The VehicleRepository interface is:
/**
* Spring Data MongoDB repository for the {#link Vehicle} entity.
*/
#Repository
public interface VehicleRepository extends MongoRepository<Vehicle, String> {
}
From the Swagger console I access the Vehicle-Resource:
Swagger console
Click on the button and write in the text box the json with the vehicle data:
enter JSON data
As we can see in the following image, the answer is 201. Initially the vehicle was saved with the identifier "id": "60e740935ed5a10e2c2ed19e".
Send request
I access the database to check that the vehicle has been correctly stored in the vehicle table. To my surprise ... there is no vehicle in the vehicle table:
show database
I can make sure that the data in the database application-dev is OK. I don't have any other databases.
I suspect that transactions with the database are not actually being made. This data is somehow stored in memory because if I do a findAllVehicles from Swagger it does return the vehicle.
I have a eureka server running (jhipster-registry) and two microservices that synchronize with it. The Gateway, which acts as a reverse proxy and the Vehiculos microservice. The Swagger console is the gateway, from where I make the request to insert vehicles. Everything seems to work, but as I say in bbdd does not save anything.

multi-tenant application in spring - connecting to DB

Hi Experts,
I am working on a multi-tenant project. It's a table per tenant architecture.
We are using spring and JPA (eclipse-link) for this purpose.
Here our use case is when ever a new customer subscribes to our application a new data base would be created for the customer.
As spring configuration would be loaded only during start-up how to load this new db configuration at run time?
Could some one please give some pointers?
Thanks in advance.
BR,
kitty
For multitenan, first you need to create MultitenantConfig.java
like below file.
here tenants.get("Musa") is my tenant name, comes from application.properties file
#Configuration
#EnableConfigurationProperties(MultitenantProperties.class)
public class MultiTenantConfig extends WebMvcConfigurerAdapter {
/** The Constant log. */
private static final Logger log = LoggerFactory.getLogger(MultiTenantConfig.class);
/** The multitenant config. */
#Autowired
private MultitenantProperties multitenantConfig;
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MultiTenancyInterceptor());
}
/**
* Data source.
*
* #return the data source
*/
#Bean
public DataSource dataSource() {
Map<Object, Object> tenants = getTenants();
MultitenantDataSource multitenantDataSource = new MultitenantDataSource();
multitenantDataSource.setDefaultTargetDataSource(tenants.get("Musa"));
multitenantDataSource.setTargetDataSources(tenants);
// Call this to finalize the initialization of the data source.
multitenantDataSource.afterPropertiesSet();
return multitenantDataSource;
}
/**
* Gets the tenants.
*
* #return the tenants
*/
private Map<Object, Object> getTenants() {
Map<Object, Object> resolvedDataSources = new HashMap<>();
for (Tenant tenant : multitenantConfig.getTenants()) {
DataSourceBuilder dataSourceBuilder = new DataSourceBuilder(this.getClass().getClassLoader());
dataSourceBuilder.driverClassName(tenant.getDriverClassName()).url(tenant.getUrl())
.username(tenant.getUsername()).password(tenant.getPassword());
DataSource datasource = dataSourceBuilder.build();
for (String prop : tenant.getTomcat().keySet()) {
try {
BeanUtils.setProperty(datasource, prop, tenant.getTomcat().get(prop));
} catch (IllegalAccessException | InvocationTargetException e) {
log.error("Could not set property " + prop + " on datasource " + datasource);
}
}
log.info(datasource.toString());
resolvedDataSources.put(tenant.getName(), datasource);
}
return resolvedDataSources;
}
}
public class MultitenantDataSource extends AbstractRoutingDataSource {
#Override
protected Object determineCurrentLookupKey() {
return TenantContext.getCurrentTenant();
}
}
public class MultiTenancyInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) {
TenantContext.setCurrentTenant("Musa");
return true;
}
}
#ConfigurationProperties(prefix = "multitenancy")
public class MultitenantProperties {
public static final String CURRENT_TENANT_IDENTIFIER = "tenantId";
public static final int CURRENT_TENANT_SCOPE = 0;
private List<Tenant> tenants;
public List<Tenant> getTenants() {
return tenants;
}
public void setTenants(List<Tenant> tenants) {
this.tenants = tenants;
}
}
public class Tenant {
private String name;
private String url;
private String driverClassName;
private String username;
private String password;
private Map<String,String> tomcat;
//setter gettter
public class TenantContext {
private static ThreadLocal<Object> currentTenant = new ThreadLocal<>();
public static void setCurrentTenant(Object tenant) {
currentTenant.set(tenant);
}
public static Object getCurrentTenant() {
return currentTenant.get();
}
}
add below properties in application.properties
multitenancy.tenants[0].name=Musa
multitenancy.tenants[0].url<url>
multitenancy.tenants[0].username=<username>
multitenancy.tenants[0].password=<password>
multitenancy.tenants[0].driver-class-name=<driverclass>

Using Green DAO with content provider get error

I use GreenDao to generate ContentProvider and when I trying to use it went wrong.it tell me "DaoSession must be set during content provider is active".I dont know where to set the DaoSession.
ContentProvider class as follows
public class ContactContentProvider extends ContentProvider {
public static final String AUTHORITY = "com.junsucc.www.provider";
public static final String BASE_PATH = "contact";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + BASE_PATH);
public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE
+ "/" + BASE_PATH;
public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE
+ "/" + BASE_PATH;
private static final String TABLENAME = ContactDao.TABLENAME;
private static final String PK = ContactDao.Properties.Id
.columnName;
private static final int CONTACT_DIR = 0;
private static final int CONTACT_ID = 1;
private static final UriMatcher sURIMatcher;
static {
sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
sURIMatcher.addURI(AUTHORITY, BASE_PATH, CONTACT_DIR);
sURIMatcher.addURI(AUTHORITY, BASE_PATH + "/#", CONTACT_ID);
}
public DaoSession daoSession=BaseApplication.getDaoSession();
#Override
public boolean onCreate() {
// if(daoSession == null) {
// throw new IllegalStateException("DaoSession must be set before content provider is created");
// }
DaoLog.d("Content Provider started: " + CONTENT_URI);
return true;
}
protected SQLiteDatabase getDatabase() {
if (daoSession == null) {
throw new IllegalStateException("DaoSession must be set during content provider is active");
}
return daoSession.getDatabase();
}
......
the error as follow
java.lang.IllegalStateException: DaoSession must be set during content provider is active
at com.junsucc.www.ContactContentProvider.getDatabase(ContactContentProvider.java:71)
at com.junsucc.www.ContactContentProvider.insert(ContactContentProvider.java:83)
at android.content.ContentProvider$Transport.insert(ContentProvider.java:220)
at android.content.ContentResolver.insert(ContentResolver.java:1190)
at com.junsucc.junsucc.MD5UtilsTest.testProvider(MD5UtilsTest.java:58)
at java.lang.reflect.Method.invokeNative(Native Method)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:554)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1701)
but I had setted th DaoSession inside my Application
public class BaseApplication extends Application {
private static Context mContext;
private static DaoMaster mDaoMaster;
private static DaoSession mDaoSession;
public static DaoMaster getDaoMaster() {
return mDaoMaster;
}
public static Context getContext() {
return mContext;
}
#Override
public void onCreate() {
mContext = getApplicationContext();
DaoMaster.OpenHelper helper = new DaoMaster.DevOpenHelper(mContext, Constants.DB_NAME, null);
mDaoMaster = new DaoMaster(helper.getWritableDatabase());
mDaoSession = mDaoMaster.newSession();
super.onCreate();
}
}
Follow the advice of the framework
/**
* This must be set from outside, it's recommended to do this inside your Application object.
* Subject to change (static isn't nice).
*/
public static DaoSession daoSession;
In your applicaction code
#Override
public void onCreate() {
super.onCreate();
DaoMaster.OpenHelper helper = new DaoMaster.DevOpenHelper(this, Constants.DB_NAME, null);
mDaoMaster = new DaoMaster(helper.getWritableDatabase());
mDaoSession = mDaoMaster.newSession();
/***********************************************/
ContactContentProvider.daoSession = mDaoSession;
/***********************************************/
}
Because ContentProvider is created ahead of Application.
So daoSession will be null when ContentProvider created.

Wicket - Load method in LoadableDetachableModel is not called after changing the value of the dropdown list

I am facing a problem with the update of a list that is filtered depending on the value of a dropdown.
This is a description of my model:
I have a list of users
When I click on a user, another list of orders of this user is
displayed
The list of orders is filtered according to the value of a dropdown
containig a list of status
Please, see the image below:
Users With orders
The filter is working well, but the problem that I am facing is that once I choose an element from the dropdown, the list of orders is no longer updated when the user is changed.
This is a snippet of my code:
Construction of the Order Panel and instantiation of the list:
public OrdersPanel(String id)
{
super(id);
this.setOutputMarkupId(true);
setOutputMarkupPlaceholderTag(true);
IModel<List<Order>> orderListModel = new OrderListModel();
orderListView = new orderListView("orderListView", orderListModel);
//...
}
OrderListModel:
private final class OrderListModel extends LoadableDetachableModel<List<Order>> {
private static final long serialVersionUID = 1L;
#Override
protected List<Order> load() {
//...
//We set the variable allOrders in order to be used later in the filtering process
//...
}
}
Construction of the dropdown:
private class StatusDropDown extends CustomDropDown<String> implements IAjaxIndicatorAware {
private static final long serialVersionUID = 1L;
private StatusDropDown(String id) {
super(id);
this.setNullValid(true);
StatusListModel statusModel = new StatusListModel();
setChoices(statusModel);
setChoiceRenderer(new StatusChoiceRenderer(statusModel));
}
#Override
protected void onUpdate(AjaxRequestTarget target) {
super.onUpdate(target);
if (target != null) {
new StatusDropDownRefreshEvent(this, target).fire();
target.addComponent(this);
}
}
/**
* disable ajax marker for the form fields
*/
public String getAjaxIndicatorMarkupId() {
return null;
}
}
CustomDropDown (Must be used by the context of the project on which I am working):
public class CustomDropDown<V> extends DropDownChoice<V> {
private static final long serialVersionUID = 1L;
public CustomDropDown(String id) {
this(id, id);
}
public CustomDropDown(String id, String property) {
super(id);
setOutputMarkupId(true);
setModel(new CustomComponentPropertyModel<V>(property));
add(new AjaxFormComponentUpdatingBehavior("onchange") {
private static final long serialVersionUID = 1L;
#Override
protected void onUpdate(AjaxRequestTarget target) {
new UpdateEvent(CustomDropDown.this, target).fire();
if (target != null) {
target.addComponent(CustomDropDown.this);
}
CustomDropDown.this.onUpdate(target);
}
});
}
#Override
protected void onComponentTag(ComponentTag tag) {
super.onComponentTag(tag);
if (!isValid()) {
tag.append("class", "invalid", " ");
FeedbackMessage message = getFeedbackMessage();
if (message != null) {
tag.put("title", message.getMessage().toString());
message.markRendered();
}
} else if (isRequired()) {
tag.append("class", "red-background", " ");
}
}
public void setWidth(String width) {
this.add(new AttributeAppender("style", true, new Model<String>("width:" + width), ";"));
}
public CustomDropDown<V> setChoices(V... choices) {
this.setChoices(Arrays.asList(choices));
return this;
}
protected void onUpdate(AjaxRequestTarget target) {
}
}
StatusDropDownRefreshEvent listener:
#AjaxUpdateEventListener
public void statusDropDownRefreshPanel(StatusDropDownRefreshEvent event){
if (event.getTarget() != null) {
orderListView.setList(getOrdersByStatus(allOrders));
event.getTarget().addComponent(this);
}
}
Changing of the user:
When the user is changed, an update event is fired from the users panel, and then cached in the orders panel:
#AjaxUpdateEventListener
public void refreshPanel(CustomerOrderRefreshEvent event) {
if (event.getTarget() != null) {
event.getTarget().addComponent(this);
this.onBeforeRender();
}
}
onBeforeRender() to determin the visibility of the panel (if no order is available then the orders panel is not visible)
#Override
public void onBeforeRender() {
setVisibilityAllowed(checkVisibility());
super.onBeforeRender();
}
Finally, the checkVisibility Method:
private boolean checkVisibility() {
if (isUserChanged()) {
List<Order> src = orderListView.getModelObject();
statusDropDown.setDefaultModelObject(null);
return CollectionUtils.isNotEmpty(src);
}
return true;
}
My main problem is that the changing of the selected user doesn't update the list of orders once a status is chosen from the list.
Thank you very much for your replies and your time.
Best regards.
I found a solution to my problem.
The list of orders wasn't updated because The method getObject was called on the wrong object.
The call of the load() method can be done via getObject(), but the condition is: The object must be detached (See the implementation of getObject() at this link)
The detached object in my case is the orderListModel and not the orderListView, so this is what I added to my code:
//Set the content of the list model
List<Order> orders = orderListModel.getObject(); //This invokes the load method
//Update the content of the list
orderListView.setList(orders);

Why SimpleBeanEditorDriver returns null values

I have a SimpleBeanEditorDriver to edit my account bean but i always get null values when i edit and call flush(). i checked everything, Google documentations, stackoverflow, google groups but didn't find any problem like. did i miss something ?
here is my View
public class AccountCreatorViewImpl extends Composite {
interface Driver extends SimpleBeanEditorDriver<Account, AccountEditor> {
}
interface AccountCreatorViewImplUiBinder extends UiBinder<HTMLPanel, AccountCreatorViewImpl> {
}
Driver driver = GWT.create(Driver.class);
private static AccountCreatorViewImplUiBinder ourUiBinder = GWT.create(AccountCreatorViewImplUiBinder.class);
private AccountCreatorPresenter presenter;
#UiField
AccountEditor accountEditor;
#UiField
Button create;
public AccountCreatorViewImpl() {
HTMLPanel rootElement = ourUiBinder.createAndBindUi(this);
initWidget(rootElement);
Account account = new Account();
driver.initialize(accountEditor);
driver.edit(account);
}
#UiHandler("create")
public void onCreate(ClickEvent event) {
Account editedAccount = driver.flush();
if (driver.hasErrors()) {
Window.alert("Has errors! ->"+driver.getErrors().toString());
}
Window.alert(editedAccount.getEmail() + "/" + editedAccount.getPassword());
// presenter.create(editedAccount);
}
}
and here is my simple editor
public class AccountEditor extends Composite implements Editor<Account> {
interface AccountEditorUiBinder extends UiBinder<HTMLPanel, AccountEditor> {
}
private static AccountEditorUiBinder ourUiBinder = GWT.create(AccountEditorUiBinder.class);
#UiField
TextBox email;
#UiField
PasswordTextBox password;
public AccountEditor() {
HTMLPanel rootElement = ourUiBinder.createAndBindUi(this);
initWidget(rootElement);
}
}
and this is my Account class
Account
public class Account implements Serializable {
private String email;
private String password;
public Account(String email) {
this.email = email;
}
public Account() {
}
public Account(String email, String password) {
this.email = email;
this.password = password;
}
public String getEmail() {
return email;
}
public String getPassword() {
return password;
}
}
i also have the same problem with another editor in my app. actually neither one works. when i press save or create i get null values of the entity.
Try adding setEmail() and setPassword() methods to your account class