On reload of page, mvp4g history mechanism fails - java

I have implemented a history mechanism for my mvp4g project. When I traverse through the pages, I can see the url also getting changed. But on reload of any page other than home page, always home page gets displayed instead of the desired page?
This is my implementation:
#History(type = HistoryConverterType.SIMPLE)
public class CustomHistoryConverter implements HistoryConverter<AppEventBus> {
private CustomEventBus eventBus;
#Override
public void convertFromToken(String historyName, String param, CustomEventBus eventBus) {
this.eventBus = eventBus;
eventBus.dispatch(historyName, param);
}
public String convertToToken(String eventName, String name) {
return name;
}
public String convertToToken(String eventName) {
return eventName;
}
public String convertToToken(String eventName, String name, String type) {
return name;
}
public boolean isCrawlable() {
return false;
}
}
and event bus related code :
#Events(startPresenter=PageOnePresenter.class,historyOnStart=true)
public interface CustomEventBus extends EventBusWithLookup {
#Start
#Event(handlers = PageOnePresenter.class)
void start();
#InitHistory
#Event(handlers = PageOnePresenter.class)
void init();
#Event(handlers = PageTwoPresenter.class, name = "page2", historyConverter = CustomHistoryConverter.class)
void getPageTwo();
#Event(handlers = PageThreePresenter.class, name = "page3", historyConverter=CustomHistoryConverter.class)
void getPageThree();
#Event(handlers=PageOnePresenter.class, name = "page1", historyConverter=CustomHistoryConverter.class)
void getPageOne();
#Event(handlers=PageOnePresenter.class)
void setPageTwo(HistoryPageTwoView view);
#Event(handlers=PageOnePresenter.class)
void setPageThree(HistoryPageThreeView view);
}

The HistoryConverter needs to be improved.
In fact, that the event has no parameter, you should return an empty string. Update the HistoryConverter that it looks like that:
#History(type = HistoryConverterType.SIMPLE)
public class CustomHistoryConverter implements HistoryConverter<AppEventBus> {
private CustomEventBus eventBus;
#Override
public void convertFromToken(String historyName, String param, CustomEventBus eventBus) {
this.eventBus = eventBus;
// TODO handle the param in cases where you have more than one parameter
eventBus.dispatch(historyName, param);
}
public String convertToToken(String eventName, String name) {
return name;
}
public String convertToToken(String eventName) {
return "";
}
public String convertToToken(String eventName, String name, String type) {
return name - "-!-" type;
}
public boolean isCrawlable() {
return false;
}
}
Hope that helps.

Related

Stub only one private static method in a class

I have a class that I am unit testing. It looks like following:
public class classToUT {
public static Event getEvent(String id) {
return getEvent(id, null);
}
private static Event getEvent(String id, String name) {
//do something
logEvent(id, name);
return event;
}
private static void logEvent(String id, string name) {
// do some logging
}
}
There are external util methods being called in logEvent that I want to avoid. Basically, I want only logEvent to be stubbed out but all other methods to be called in my unit test. How do I stub out this one method only?
public void UTClass {
#Test
public void testGetEvent() {
assertNotNull(event, classToUt.getEvent(1)); //should not call logEvent
//but call real method for getEvent(1) and getEvent(1, null)
}
}
Try the following ...
#RunWith(PowerMockRunner.class)
#PrepareForTest(PowerTest.ClassToUT.class)
public class PowerTest {
public static class ClassToUT {
public static String getEvent(String id) {
return getEvent(id, null);
}
private static String getEvent(String id, String name) {
// do something
logEvent(id, name);
return "s";
}
private static void logEvent(String id, String name) {
throw new RuntimeException();
}
}
#Test
public void testGetEvent() throws Exception {
PowerMockito.spy(ClassToUT.class);
PowerMockito.doNothing().when(ClassToUT.class, "logEvent", any(), any());
Assert.assertEquals("s", ClassToUT.getEvent("xyz"));
}
}

GWT - How to change NumberConstants in NumberFormat

I need to change NaN value and Minus sign in NumberFormat's NumberConstants.
It's impossible to change NumberConstants "on the fly", so I decided to subclass NumberFormat.
NumberFormat's constructor annotation says:
#param numberConstants the locale-specific number constants to use for
this format -- NOTE subclasses passing their own instance here
should pay attention to {#link #forcedLatinDigits()} and remap
localized symbols using {#link #createLatinNumberConstants(NumberConstants)}
It seemes what I should call setForcedLatinDigits(true) in order method createLatinNumberConstants(NumberConstants) to be executed. Then localized constants will be updated by that (createLatinNumberConstants) method, and I will get NumberConstants which I need.
Here is my code:
public class MyNumberFormat extends NumberFormat {
protected MyNumberFormat(String pattern, CurrencyData cdata, boolean userSuppliedPattern) {
this(defaul, pattern, cdata, userSuppliedPattern);
}
protected MyNumberFormat(NumberConstants numberConstants, String pattern, CurrencyData cdata, boolean userSuppliedPattern) {
super(numberConstants, pattern, cdata, userSuppliedPattern);
}
public static MyNumberFormat getFormat(String pattern) {
return new MyNumberFormat(pattern, CurrencyList.get().getDefault(), true);
}
protected static NumberConstants createLatinNumberConstants(
final NumberConstants orig) {
final String groupingSeparator = remapSeparator(
orig.groupingSeparator());
final String decimalSeparator = remapSeparator(
orig.decimalSeparator());
final String monetaryGroupingSeparator = remapSeparator(
orig.monetaryGroupingSeparator());
final String monetarySeparator = remapSeparator(
orig.monetarySeparator());
return new NumberConstants() {
#Override
public String currencyPattern() {
return orig.currencyPattern();
}
#Override
public String decimalPattern() {
return orig.decimalPattern();
}
#Override
public String decimalSeparator() {
return decimalSeparator;
}
#Override
public String defCurrencyCode() {
return orig.defCurrencyCode();
}
#Override
public String exponentialSymbol() {
return orig.exponentialSymbol();
}
#Override
public String globalCurrencyPattern() {
return orig.globalCurrencyPattern();
}
#Override
public String groupingSeparator() {
return groupingSeparator;
}
#Override
public String infinity() {
return orig.infinity();
}
#Override
public String minusSign() {
return UnicodeSymbols.MINUS;
}
#Override
public String monetaryGroupingSeparator() {
return monetaryGroupingSeparator;
}
#Override
public String monetarySeparator() {
return monetarySeparator;
}
#Override
public String notANumber() {
return "?";
}
#Override
public String percent() {
return orig.percent();
}
#Override
public String percentPattern() {
return orig.percentPattern();
}
#Override
public String perMill() {
return orig.perMill();
}
#Override
public String plusSign() {
return orig.plusSign();
}
#Override
public String scientificPattern() {
return orig.scientificPattern();
}
#Override
public String simpleCurrencyPattern() {
return orig.simpleCurrencyPattern();
}
#Override
public String zeroDigit() {
return "0";
}
};
}
}
So in order to format number i will execute this:
String fmt(final Double x){
MyNumberFormat.setForcedLatinDigits(true);
MyNumberFormat format = MyNumberFormat.getFormat("0.0000");
return format.format(x)
}
But in fact createLatinNumberConstants is protected static method and it can't be overriden or substituted.
So MyNumberFormat.createLatinNumberConstants() is never executed.
What am I doing wrong?
I think you do not need to overwrite createLatinNumberConstants - instead you pass your number constants to the constructor of the super class.
as a base you can use the default number constants of NumberFormat.
Something like that should work:
public class MyNumberFormat extends NumberFormat {
protected MyNumberFormat(String pattern, CurrencyData cdata, boolean userSuppliedPattern) {
super(createMyNumberConstants(NumberFormat.defaultNumberConstants), pattern, cdata, userSuppliedPattern);
}
public static MyNumberFormat getFormat(String pattern) {
return new MyNumberFormat(pattern, CurrencyList.get().getDefault(), true);
}
protected static final NumberConstants createMyNumberConstants(
final NumberConstants orig) {
return new NumberConstants() {
#Override
public String currencyPattern() {
return orig.currencyPattern();
}
#Override
public String decimalPattern() {
return orig.decimalPattern();
}
#Override
public String decimalSeparator() {
return decimalSeparator();
}
#Override
public String defCurrencyCode() {
return orig.defCurrencyCode();
}
#Override
public String exponentialSymbol() {
return orig.exponentialSymbol();
}
#Override
public String globalCurrencyPattern() {
return orig.globalCurrencyPattern();
}
#Override
public String groupingSeparator() {
return orig.groupingSeparator();
}
#Override
public String infinity() {
return orig.infinity();
}
#Override
public String minusSign() {
return orig.minusSign();
}
#Override
public String monetaryGroupingSeparator() {
return orig.monetaryGroupingSeparator();
}
#Override
public String monetarySeparator() {
return orig.monetarySeparator();
}
#Override
public String notANumber() {
return "?";
}
#Override
public String percent() {
return orig.percent();
}
#Override
public String percentPattern() {
return orig.percentPattern();
}
#Override
public String perMill() {
return orig.perMill();
}
#Override
public String plusSign() {
return orig.plusSign();
}
#Override
public String scientificPattern() {
return orig.scientificPattern();
}
#Override
public String simpleCurrencyPattern() {
return orig.simpleCurrencyPattern();
}
#Override
public String zeroDigit() {
return "0";
}
};
}

OSGi - Registering a service from a different bundle

I have recently started learning OSGi. While experimenting with Apache Aries and OSGi blueprint, I created the following set-up:
Bundle A :
public interface IMessageSender {
String send(String message);
String getServiceName();
}
public interface IMessageSenderFactory {
String name();
IMessageSender create();
}
Bundle B (SMSSenderFactory is exported as a service):
public class SMSSender implements IMessageSender {
public String send(String message) {
return "Sent by SMS : "+message;
}
public String getServiceName() {
return "SMS";
}
}
public class SMSSenderFactory implements IMessageSenderFactory {
public String name() {
return "SMS";
}
public IMessageSender create() {
return new SMSSender();
}
}
Bundle C :
public class BundleManagerImpl implements BundleManager{
BundleContext bundleContext;
Map<IMessageSenderFactory, List<ServiceRegistration>> senders = new HashMap<IMessageSenderFactory, List<ServiceRegistration>>();
public void setBundleContext(BundleContext bundleContext) {
this.bundleContext = bundleContext;
}
//reference listener method
public void addSenderFactory(IMessageSenderFactory senderFactory) {
this.senders.put(senderFactory, new ArrayList<ServiceRegistration>());
}
//reference listener method
public void removeSenderFactory(IMessageSenderFactory senderFactory){
List<ServiceRegistration> registeredSenders = this.senders.get(senderFactory);
if (registeredSenders != null){
for (ServiceRegistration serviceRegistration : registeredSenders) {
serviceRegistration.unregister();
}
}
this.senders.remove(senderFactory);
}
#Override
public List<String> listFactories(){
List<String> list = new ArrayList<String>();
for (IMessageSenderFactory senderFactory : senders.keySet()) {
list.add(senderFactory.name());
}
return list;
}
#Override
public void createSenderServiceInstance(String type){
IMessageSender sender = null;
for (IMessageSenderFactory senderFactory : senders.keySet()) {
if (senderFactory.name().equals(type)){
sender = senderFactory.create();
ServiceRegistration registration = bundleContext.registerService(IMessageSender.class.getName(), sender, null);
this.senders.get(senderFactory).add(registration);
}
}
}
}
Bundle D:
public class MessageServiceImpl implements MessageService {
List<IMessageSender> senders = new ArrayList<IMessageSender>();
//reference listener method
public void addSender(IMessageSender sender) {
this.senders.add(sender);
}
//reference listener method
public void removeSender(IMessageSender sender){
this.senders.remove(sender);
}
public List<String> send(String message) {
List<String> list = new ArrayList<String>();
for (IMessageSender sender : this.senders) {
String response = sender.send(message);
list.add(MessageFormat.format("Sent by : {0}; Response : {1}", sender.getServiceName(), response));
}
return list;
}
}
The goal was to allow creation of multiple, variable number of instances of the SMSSender service.
So my questions are:
1 - Is there anything wrong with this approach? I am creating an SMSSender instance, in bundle B and registering it as a service in Bundle C. Would this lead to any issues or does it violate any rule of OSGi?
2 - Are there any other approaches to reaching the same goal?
EDIT:
Bundle E (added later, exports EmailSenderFactory as service)
public class EmailSender implements IMessageSender {
public String send(String message) {
return "Sent by Email : "+message;
}
public String getServiceName() {
return "Email";
}
}
public class EmailSenderFactory implements IMessageSenderFactory {
public String name() {
return "Email";
}
public IMessageSender create() {
return new EmailSender();
}
}

Passing a collection of a subclass as collection of superclass

I have a POJO that looks more or less like this:
public class Action {
private String eventId;
private List<ActionArgument> arguments;
//action to perform when this action is done
private List<Action> onCompleteActions;
public Action() {
}
public Action(String eventId, List<ActionArgument> arguments, List<Action> onCompleteActions) {
this.eventId = eventId;
this.arguments = arguments;
this.onCompleteActions = onCompleteActions;
}
public String getEventId() {
return eventId;
}
public void setEventId(String eventId) {
this.eventId = eventId;
}
public List<ActionArgument> getArguments() {
return arguments;
}
public void setArguments(List<ActionArgument> arguments) {
this.arguments = arguments;
}
public List<Action> getOnCompleteActions() {
return onCompleteActions;
}
public void setOnCompleteAction(List<Action> onCompleteActions) {
this.onCompleteActions = onCompleteActions;
}
}
and I have an extending class that looks like this:
public class UserDefinedAction extends Action {
//for reordering actions with the default actions
private String doBefore;
private String doAfter;
private String doAfterComplete;
public String getDoBefore() {
return doBefore;
}
public void setDoBefore(String doBefore) {
this.doBefore = doBefore;
}
public String getDoAfter() {
return doAfter;
}
public void setDoAfter(String doAfter) {
this.doAfter = doAfter;
}
public String getDoAfterComplete() {
return doAfterComplete;
}
public void setDoAfterComplete(String doAfterComplete) {
this.doAfterComplete = doAfterComplete;
}
}
Elsewhere I have a service I would like to do this:
...
UserDefinedAction udAction = new UserDefinedAction();
udAction.setOnCompleteAction(new ArrayList<UserDefinedAction>());
I thought this should work because a UserDefinedAction IS an Action because its extending it right?
List<UserDefinedAction> is not a subclass of List<Action> even if UserDefinedAction extends Action. In order you can pass a List<UserDefinedAction> to your service, change the UserDefinedAction#setOnCompleteAction method to receive a List<? extends Action>, now you can pass a new ArrayList<UserDefinedAction>().
More info:
Generics: Wildcards
Your UserDefinedAction may be an Action, but a List<Subclass> is not a List<Superclass>. As you have defined it, your setOnCompleteAction method must take a List<Action>, so it cannot accept a List<UserDefinedAction>.

java- error when i am trying to convert xml response into pojo using xstream

I am getting an error for the following code in a java web app--
XStream xstream = new XStream();
apiresponse myClassObject;
myClassObject= xstream.fromXML(resp);
The error is shown for the line of code just above this line--
error="Type mismatch- cannot convert from Object to apiresponse"
Given below is the XML that I have to parse---
<apiresponse version="1" xmlns="http://ahrefs.com/schemas/api/links/1">
<resultset_links count="2">
<result>
<source_url>http://ahrefs.com/robot/</source_url>
<destination_url>http://blog.ahrefs.com/</destination_url>
<source_ip>50.22.24.236</source_ip>
<source_title>Ahrefs – backlinks research tool</source_title>
<visited>2011-08-31T07:56:53Z</visited>
<anchor>Blog</anchor>
<rating>257.674000</rating>
<link_type>text</link_type>
<is_nofollow>false</is_nofollow>
</result>
<result>
<source_url>http://apps.vc/</source_url>
<destination_url>http://ahrefs.com/robot/</destination_url>
<source_ip>64.20.55.86</source_ip>
<source_title>Device info</source_title>
<visited>2011-08-27T18:59:31Z</visited>
<anchor>http://ahrefs.com/robot/</anchor>
<rating>209.787100</rating>
<link_type>text</link_type>
<is_nofollow>false</is_nofollow>
</result>
</resultset_links>
</apiresponse>
I have created the following java classes to obtain data from above xml---
package com.arvindikchari.linkdatasmith.domain;
final public class apiresponse {
protected resultset_links rlinks;
public apiresponse() {
}
public resultset_links getRlinks()
{
return rlinks;
}
public setRlinks(resultset_links rlinks)
{
this.rlinks=rlinks;
}
}
final public class resultset_links {
protected List<result> indiv_result = new ArrayList<result>();
public resultset_links() {
}
public List<result> getIndiv_result()
{
return List;
}
public void setIndiv_result(List<result> indiv_result)
{
this.indiv_result=indiv_result;
}
}
final public class result {
protected String source_url;
protected String destination_url;
protected String source_ip;
protected String source_title;
protected String visited;
protected String anchor;
protected String rating;
protected String link_type;
public result() {
}
public String getSource_url()
{
return source_url;
}
public void setSource_url(String source_url)
{
this.source_url=source_url;
}
public String getDestination_url()
{
return destination_url;
}
public void setDestination_url(String destination_url)
{
this.destination_url=destination_url;
}
public String getSource_ip()
{
return source_ip;
}
public void setSource_ip(String source_ip)
{
this.source_ip=source_ip;
}
public String getSource_title()
{
return source_title;
}
public void setSource_title(String source_title)
{
this.source_title=source_title;
}
public String getVisited()
{
return visited;
}
public void setVisited(String visited)
{
this.visited=visited;
}
public String getAnchor()
{
return anchor;
}
public void setAnchor(String anchor)
{
this.anchor=anchor;
}
public String getRating()
{
return rating;
}
public void setRating(String rating)
{
this.rating=rating;
}
public String getLink_type()
{
return link_type;
}
public void setLink_type(String link_type)
{
this.link_type=link_type;
}
}
What am I doing wrong here?
You have many errors, but the one corresponding to your message is you have to cast the result of xstream.fromXML to an apiresponse' object :
apiresponse result = (apiresponse)xstream.fromXML(resp);
Moreover, the code you provided (the Java classes) do not compile, there are many errors.
Here are some improvements :
Result.java :
#XStreamAlias("result")
public class Result {
protected String source_url;
protected String destination_url;
protected String source_ip;
protected String source_title;
protected String visited;
protected String anchor;
protected String rating;
protected String link_type;
protected Boolean is_nofollow;
public Result() {
}
public String getSource_url()
{
return source_url;
}
public void setSource_url(String source_url)
{
this.source_url=source_url;
}
public String getDestination_url()
{
return destination_url;
}
public void setDestination_url(String destination_url)
{
this.destination_url=destination_url;
}
public String getSource_ip()
{
return source_ip;
}
public void setSource_ip(String source_ip)
{
this.source_ip=source_ip;
}
public String getSource_title()
{
return source_title;
}
public void setSource_title(String source_title)
{
this.source_title=source_title;
}
public String getVisited()
{
return visited;
}
public void setVisited(String visited)
{
this.visited=visited;
}
public String getAnchor()
{
return anchor;
}
public void setAnchor(String anchor)
{
this.anchor=anchor;
}
public String getRating()
{
return rating;
}
public void setRating(String rating)
{
this.rating=rating;
}
public String getLink_type()
{
return link_type;
}
public void setLink_type(String link_type)
{
this.link_type=link_type;
}
public Boolean getIs_nofollow() {
return is_nofollow;
}
public void setIs_nofollow(Boolean is_nofollow) {
this.is_nofollow = is_nofollow;
}
ResultsetLinks.java :
#XStreamAlias("resultset_links")
public class ResultsetLinks {
#XStreamImplicit(itemFieldName="result")
protected List<Result> indivResult = new ArrayList<Result>();
public ResultsetLinks() {
}
public List<Result> getResult()
{
return indivResult;
}
public void setResult(List<Result> indiv_result)
{
this.indivResult =indiv_result;
}
}
ApiResponse.java :
#XStreamAlias("apiresponse")
public class ApiResponse {
#XStreamAlias("resultset_links")
protected ResultsetLinks rlinks;
public ApiResponse() {
}
public ResultsetLinks getRlinks()
{
return rlinks;
}
public void setRlinks(ResultsetLinks rlinks)
{
this.rlinks=rlinks;
}
}
And finally your code to unmarshall the XML :
XStream xstream = new XStream();
xstream.processAnnotations(ApiResponse.class);
xstream.processAnnotations(ResultsetLinks.class);
xstream.processAnnotations(Result.class);
ApiResponse result = (ApiResponse)xstream.fromXML(resp);
All this code is working fine with Xstream 1.4.2
Try to follow Sun's coding convention for your classes name, attributes names, etc...
Use XstreamAliases to adapt the Java class name to the XML name.

Categories

Resources