Getting a map from PageParameters in Wicket 1.5 - wicket

I'm trying to migrate an application using OpenId4Java to Wicket 1.5. Using the migration notes I've gotten everything to work.
Except one thing: Before Wicket 1.5 PageParameters was a map which was perfect since OpenId4Java's ParameterList took an map as an argument.
However in Wicket 1.5, I can't figure out how to get an map out of the PageParameters.
Going trough the PageParameters NamedPairs and making a map of of that is not to hard. But creating an class (the creation of a ParameterLists are in several places) does not feel as a good solution.
What is the simpler solution to this?
ParameterList response = new ParameterList( pageParameters);
-- EDIT --
Code that solved the problem for me.
public static ParameterList toParameterList(PageParameters p){
HashMap<String, String> h = new HashMap<String, String>();
for(NamedPair pair: p.getAllNamed()){
h.put(pair.getKey(), pair.getValue());
}
return new ParameterList(h);
}
public static ParameterList toParameterList(IRequestParameters rP) {
HashMap<String, String> h = new HashMap<String, String>();
for(String name : rP.getParameterNames()){
h.put(name, rP.getParameterValue(name).toString());
}
return new ParameterList(h);
}

See http://apache-wicket.1842946.n4.nabble.com/Upgrade-1-5-PageParameters-toRequestParameters-tp3871781p3873818.html for the same issue.
The closest is org.apache.wicket.request.mapper.parameter.PageParameters.getAllNamed() You can write a helper function to convert it to Map

Related

Register commandHandler with EventList in a Nattable with Filters

As a suggestion from question Nattable add row command I tried to register a command handler with an EventList.
But since the Eventlist is wrapped by a FilterList which acts as BodyDataProvider I could not create a DataLayer based in EventList from which I could register my CommmandHandler.
The starting point is the previous question to define a BodyLayerStack with the following:
class BodyLayerStack extends AbstractLayerTransform {
//AncolabMaterial is the model to show at the natTable
private final EventList<AncolabMaterial> filterList;
private final IDataProvider bodyDataProvider;
private final SelectionLayer selectionLayer;
public BodyLayerStack(List<AncolabMaterial> input_values_list, IColumnPropertyAccessor<AncolabMaterial> columnPropertyAccessor) {
EventList<AncolabMaterial> eventList = GlazedLists.eventList(input_values_list);
TransformedList<?, ?> rowObjectsGlazedList = GlazedLists.threadSafeList(eventList);
SortedList<?> sortedList = new SortedList<>(rowObjectsGlazedList, null);
this.filterList = new FilterList<AncolabMaterial>((EventList<AncolabMaterial>) sortedList);
this.bodyDataProvider = new ListDataProvider<AncolabMaterial>(filterList, columnPropertyAccessor);
DataLayer bodyDataLayer = new DataLayer(getBodyDataProvider());
//Other layers stacked
GlazedListsEventLayer<?> glazedListsEventLayer = new GlazedListsEventLayer<AncolabMaterial>(bodyDataLayer, this.filterList);
this.selectionLayer = new SelectionLayer(glazedListsEventLayer, false);
//...
}
}
I have tried the following:
DataLayer dataLayer = new DataLayer(
new ListDataProvider<AncolabMaterial>(eventList, columnPropertyAccessor));
But since DataLayer wraps the IDataProvider, and serves as the data source for all other layers, If I sets the EvenList as the IDataProvider of the DataLayer then filterlList is not working properly.
i.e. this.filterList is not the base of the bodyDataProvider.
I have not find at nattable_examples -> tutorial examples -> GlazedLists -> Filter any other BodyLayerStack configuration different than the above.
There seems to be a big misunderstanding with regards to the list instances. If you want to use the filter functionality the shown BodyLayerStack is correct. You have to use the FilterList in the IDataProvider. There is absolutely now reason to change that!
For the command handler you need to use the base EventList instance. Of course that does not work if you use the list that you get from the IDataProvider. You need to provide the access to the EventList in another way. From the snippets you show in this and in the other related post, I don't see a reason why you access the underlying list via IDataProvider, but as you already noticed, that does not work. You need to change your code structure.

Is using default method in an interface a good pattern to avoid code duplications?

We have a lot of code duplication in data holder classes that can be serialized to a XML string:
public String toXml() throws JAXBException {
final JAXBContext context = JAXBContext.newInstance(this.getClass());
final Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
final StringWriter stringWriter = new StringWriter();
marshaller.marshal(this, stringWriter);
return stringWriter.toString();
}
Why not move this code to a single interface with default implementation? So a simple implements ToXmlUtf8 would be enough to share the default implementation and avoid code duplicates:
public interface ToXml {
default String toXml() throws JAXBException {
final JAXBContext context = JAXBContext.newInstance(this.getClass());
final Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
final StringWriter stringWriter = new StringWriter();
marshaller.marshal(this, stringWriter);
return stringWriter.toString();
}
}
Has anybody done this before successfully?
Other solutions?
I could also imagine using an annotation to generate this code.
Are there any ready to use solutions available?
Yes, default methods can be used in that way.
Although the intended use case of default methods is adding new functionality to existing interfaces without breaking old code, default methods have other uses as well. Default methods are also used in interfaces which were added in Java 8, such as in java.util.Predicate, so even the Java designers recognized that adding new functionality to existing interfaces is not the only valid use of default methods.
A disadvantage could be that the implemented interfaces are part of a class's public contract, but in your case this does not seem to be a problem.
If you're using the exact same method then an interface won't help, what you want to do is make a static method and put that in a util class

Where to place Rythm template files

I am having a weird problem with Rythm templates. Currently, I have these templates placed under
myPrj/src/main/java/resources/templates folder.
And all the Java source code is under myPrj/src/main/java folder.
When I try to render, sometimes Rythm is generating the XML file and sometimes I get the file name as is.
I have the home.template set to "templates" folder:
params.put("home.template", "templates");
String myTemplateString = Rythm.render("MyTemplate.xml", parameters);
Looks like Rythm is not able to locate MyTemplate.xml and resulting in emitting MyTemplate.xml as the output.
Can you please help me on how to solve this problem?? In addition, would appreciate if you can guide me on what should be the appropriate location to place these templates.
home.template is the configuration key to initialize template engine, not the parameter to render your template.
My implementation of your app looks like
public class App {
private static RythmEngine engine;
private static void echo(String msg, Object ... args) {
System.out.println(String.format(msg, args));
}
private static void init() {
echo("initializing rythmengine");
Map<String, Object> conf = new HashMap<String, Object>();
conf.put("home.template", "templates");
engine = new RythmEngine(conf);
echo("engine initialized");
}
private static void render() {
Map<String, Object> params = new HashMap<String, Object>();
params.put("foo", "FOO");
params.put("bar", "BAR");
String result = engine.render("MyTemplate.xml", params);
echo(result);
}
private static void doJob() {
echo("start doing real job now...");
render();
}
public static void main( String[] args ) {
init();
doJob();
}
}
The complete sample code could be found at https://github.com/greenlaw110/Rythm/tree/master/samples/demo_fo_SO_150529. Download the sample code and run mvn compile exec:java to see the result
It seems your problem lies within the path for the home.template. The example on their website might help.
If I'm not mistaken, you should use params.put("home.template", "resources/templates"); rather than params.put("home.template", "templates");.
Generally speaking, this kind of behaviour takes place any time Rythm can't find the template. I found it is best to check both, the path and file name. If necessary, simply use an absolute path to your template to make sure it points to the right directory. After you got the right path, you might want to change it back to be relative.

In Nunit, Compare two lists of objects so that they contain the same types

I am writing an EFException converter and I am building a Rulset for it. I want to verify that the builder returns a list of the rules:
[Test]
public void Build_CreateListOfEntityRules()
{
//arrange
var expected = new List<IEntityRule>
{
new AutomaticDataLossEntityRule(),
new CommitFailedEntityRule(),
new DbEntityValidationEntityRule(),
new DbUnexpectedValidationEntityRule(),
new DbUpdateConcurrencyEntityRule(),
new DbUpdateEntityRule(),
new EntityCommandCompliationEntityRule(),
new EntityCommandExecutionEntityRule(),
new EntityErrorEntityRule(),
new EntitySqlEntityRule(),
new InvalidOperation(),
new MigrationEntityRule(),
new MigrationsPendingEntityRule(),
new ModelValidationEntityRule(),
new ObjectNotFound(),
new PropertyConstraintEntityRule(),
new UnintentionalCodeFirstEntityRule(),
new UpdateEntityRule()
};
//act
var actual = sut.Build();
//assert
CollectionAssert.AreEquivalent(expected, actual);
}
Collection.AreEquivilent, Collection.AreEqual, and Collection.Contains all fail; however, when I manually look at the output of the lists they are the same.
Why doesn't NUnit recognize this?
If the test fail and you wouldn't expect it to, then I guess you are not implementing Equals method for some of your classes properly (possibly none of them), because that is the method which ultimately gets called when asserting collections of objects.
If method is not implemented in any of IEntityRule implementations then Equals method of class object is called instead which returns false when compared objects are not the same instance.
To sum it up - solution is to implement public bool Equals(AutomaticDataLossEntityRule other) for AutomaticDataLossEntityRule class and similarly for the rest of the classes.

JBehave doesn't recognize steps, but does load the steps file

With a different test runner (the annotation based one) the steps get picked up and run. The annotation based approach doesn't seem to support a steps factory though, so I swapped models. Now, it will load the steps class (some visible things happen when the constructor is called) but it won't recognize any of the steps inside it. Any ideas? Here's my embedder class:
public class LoginAcceptanceFull extends JUnitStories {
private final CrossReference xref = new CrossReference();
public LoginAcceptanceFull() {
configuredEmbedder().embedderControls().doGenerateViewAfterStories(true)
.doIgnoreFailureInStories(true).doIgnoreFailureInView(true).useThreads(2)
.useStoryTimeoutInSecs(60);
}
#Override
public Configuration configuration() {
Class<? extends Embeddable> embeddableClass = this.getClass();
Properties viewResources = new Properties();
viewResources.put("decorateNonHtml", "true");
// Start from default ParameterConverters instance
ParameterConverters parameterConverters = new ParameterConverters();
// factory to allow parameter conversion and loading from external
// resources (used by StoryParser too)
ExamplesTableFactory examplesTableFactory = new ExamplesTableFactory(new LocalizedKeywords(),
new LoadFromClasspath(embeddableClass), parameterConverters);
// add custom converters
parameterConverters.addConverters(new DateConverter(new SimpleDateFormat("yyyy-MM-dd")),
new ExamplesTableConverter(examplesTableFactory));
return new MostUsefulConfiguration()
.useStoryControls(new StoryControls().doDryRun(false).doSkipScenariosAfterFailure(false))
.useStoryLoader(new LoadFromURL())
.useStoryParser(new RegexStoryParser(examplesTableFactory))
.useStoryPathResolver(new UnderscoredCamelCaseResolver())
.useStoryReporterBuilder(
new StoryReporterBuilder()
.withCodeLocation(CodeLocations.codeLocationFromClass(embeddableClass))
.withDefaultFormats().withPathResolver(new ResolveToPackagedName())
.withViewResources(viewResources).withFormats(org.jbehave.core.reporters.Format.HTML,
org.jbehave.core.reporters.Format.TXT, org.jbehave.core.reporters.Format.XML)
.withFailureTrace(true).withFailureTraceCompression(true).withCrossReference(xref))
.useParameterConverters(parameterConverters)
.useStepPatternParser(new RegexPrefixCapturingPatternParser("%"))
.useStepMonitor(xref.getStepMonitor());
}
#Override
public InjectableStepsFactory stepsFactory(){
return new InstanceStepsFactory(configuration(), new LoginSteps());
}
#Override
protected List<String> storyPaths(){
String codeLocation = org.jbehave.core.io.CodeLocations.codeLocationFromClass(this.getClass()).getFile();
return new StoryFinder().findPaths(codeLocation, asList("**/login_trial.story"),
asList(""), "file:" + codeLocation);
}
}
I found it. Right here was the culprit:
.useStepPatternParser(new RegexPrefixCapturingPatternParser("%"))
It was causing JBehave to not recognize the #Given annotations and so JBehave assumed everything needed a step and listed them all as pending (or skipped them because they were missing the #Given step). Once I pulled that part of the configuration everything was cool.