Instance variable in Stripes - instance-variables

I'm trying to find a way to create an instance variable within the Stripes application context.
Something that i would do in the init() method of a Servlet while using hand-coded servlets.
The problem is that since an instance of the ActionBean is created each time the application is accessed, the variable in the actionBean is created multiple time.
I have tried to get some reasonable place withing Stripes trying to call the ServletContext via ActionBeanContext.getServletContext(), but from there there is no way to access the init() method and write some code in it.
Do you have any suggestions?

The ActionBeanContext is also Stripes application context. This context can be customized and can contain whatever you want. Some example code:
package my.app;
public class CustomActionBeanContext extends ActionBeanContext {
public CustomActionBeanContext() {
super();
}
public MyObject getMyObject() {
return (MyObject) getServletContext().getAttribute(“myObject”);
}
// Alternative solution without ServletContextListner
private static MyObject2 myObject2;
static {
myObject2 = new MyObject2();
}
public MyObject2 getMyObject2() {
return myObject2;
}
}
To let the Stripes context factory know you want to use a custom ActionBeanContext you need to add an init-param to the Stripes filter in the web.xml:
<init-param>
<param-name>ActionBeanContext.Class</param-name>
<param-value>my.app.CustomActionBeanContext</param-value>
</init-param>
You can initialize your object at server start by adding a SerlvetContextListener:
Public class MyServletContextListener implements ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent event) {
event.getServletContext().setAttribute("myObject", new MyObject());
}
Example ActionBean:
public class MyAction implements ActionBean {
private CustomActionBeanContext context;
#Override
public CustomActionBeanContext getContext() {
return context;
}
#Override
public void setContext(ActionBeanContext context) {
this.context = (CustomActionBeanContext) context;
}
#DefaultHandler
public Resolution view() {
MyObject myObject = getContext().getMyObject();
// doing something usefull with it..
}
}
An alternative solution, in my opinion a superiour solution, is to use a dependency injection framework for injecting the (singleton) objects into your actionbeans. See Stripes configuration example here: Injecting Stripes ActionBeans with Guice DI

Not a Stripes-specific way, but using the standard Servlet API you'd implement ServletContextListener and do the job in contextInitialized() method. If you register it as <listener> in web.xml (or when you're already on Java EE 6, annotate using #WebListener), then it'll run during webapp's startup.
#Override
public void contextInitialized(ServletContextEvent event) {
event.getServletContext().setAttribute("somename", new SomeObject());
}
This way it's available in EL by ${somename} and in all action beans by ServletContext#getAttribute().

#JBoy, You have to specify your implementation of ServletContextListner in the web.xml like below
<listner>
<listner-class>
www.test.com.MyListner
</listner-class>
</listner>
Thanks KDeveloper for his advice. I was also searching for the solution. I found the information from his blog
There is one more method I have found out. For that you have to subclass the "RuntimeConfiguration" class
public class MyConfiguration extends RuntimeConfiguration {
#Override
public void init() {
getServletContext.setAttribute("myObject",new MyObject);
super.init();
}
}
After that in the web.xml specify the above configuration.
<init-param>
<param-name>Configuration.Class</param-name>
<param-value>www.test.com.MyConfiguration</param-value>
</init-param>
You also have to subclass the ActionBeanContext as KDeveloper said; to get the object in ActionBeans
This is my finding. I found out it is working. But I don't know whether it has any side effects. If it has any; please comment..

Related

OSGI - two objects of a bundle service

I have a bundle that provides a service.
My bundle implementation looks like this:
class ServiceImpl implements Service
{
Object value;
#Override
public void setValue(Object value)
{
this.value = value;
}
#Override
public Object getValue()
{
return value;
}
}
In my java application, I load this bundle to OSGI framework, and create TWO references to the service, in an attempt to have two objects with different values for "value".
Unfortunately, this does not seem to work. The service always returns the last value set by either objects. How can I overcome this issue?
Here's an example for the problem:
Service object1 = context.getService(reference1);
Service object2 = context.getService(reference2);
Integer one= 1;
Integer two =2;
object1.setValue(1);
object2.setValue(2);
System.out.println(object1.getValue() ); //returns 2 !!!!!!!!!!!!!!!!!!
System.out.println(object2.getValue() ); //returns 2
I used ServiceFactory but it seems not useful for my case. What should I do? Thanks.
Both BJ and Balazs offer valuable information, but no solution that works with current versions of the OSGi specification.
What you can do is register your service with a second "Factory" interface. This factory then allows you to create instances of the service. Because you probably don't want to do that manually, you can hide this logic in a ServiceTracker.
There are a few "downsides" to this approach. First of all, you need to register the service and have the instance implement both Factory and Service. Secondly, you always have to use this custom ServiceTracker to access it. If you use a dependency manager that allows you to extend its dependencies (such as Apache Felix Dependency Manager) you can easily hide all of this in a custom ServiceDependency.
Anyway, to show you that this actually works, here is a simple example:
public class Activator implements BundleActivator {
#Override
public void start(final BundleContext context) throws Exception {
context.registerService(Service.class.getName(), new FactoryImpl(), null);
ServiceTrackerCustomizer customizer = new ServiceTrackerCustomizer() {
#Override
public Object addingService(ServiceReference reference) {
Object service = context.getService(reference);
if (service instanceof Factory) {
return ((Factory) service).createInstance();
}
return service;
}
#Override
public void modifiedService(ServiceReference reference,
Object service) {
// TODO Auto-generated method stub
}
#Override
public void removedService(ServiceReference reference,
Object service) {
// TODO Auto-generated method stub
}
};
ServiceTracker st1 = new ServiceTracker(context, Service.class.getName(), customizer);
ServiceTracker st2 = new ServiceTracker(context, Service.class.getName(), customizer);
st1.open();
st2.open();
Service s1 = (Service) st1.getService();
Service s2 = (Service) st2.getService();
s1.setValue("test1");
s2.setValue("test2");
System.out.println(s1.getValue());
System.out.println(s2.getValue());
}
#Override
public void stop(BundleContext context) throws Exception {
}
static interface Factory {
public Object createInstance();
}
static class FactoryImpl extends ServiceImpl implements Factory, Service {
#Override
public Object createInstance() {
return new ServiceImpl();
}
}
static interface Service {
public void setValue(Object value);
public Object getValue();
}
static class ServiceImpl implements Service {
private Object m_value;
#Override
public void setValue(Object value) {
m_value = value;
}
#Override
public Object getValue() {
return m_value;
}
}
}
You need to wait for R6. Pre-R6, each bundle can be exposed to at most one instance of a service. Even registering a ServiceFactory will not change that since the framework will cache the service object from the ServiceFactory to return to the bundle on subsequent calls to getService.
In R6, we introduce service scopes which allows a service implementation to return multiple service objects to a bundle. Using this requires both the service provider and the service consumer to use new API added in R6.
You can play with this now as it is implemented in Eclipse Equinox Luna.
Even if you use ServiceFactory, for the same bundle the same service object will be returned.
There might be a PrototypeServiceFactory in the future as there is an RFP about it: https://github.com/osgi/design/tree/master/rfcs/rfc0195
That would fit to your needs.
Although there might be a PrototypeServiceFactory in the future, I think it is better to solve this use-case programmatically by yourself. E.g.:
Instead of creating a mutuable OSGi service (I do not think creating mutuable services is a good idea) create a factory.
On the client side you would use:
BusinessLogicFactory factory = context.getService(reference);
BusinessLogic object1 = factory.createInstance();
BusinessLogic object2 = factory.createInstance();
...

Jbehave get Story name inside #BeforeStory

I would like to get the Story name in a method annotated with #BeforeStory.
I need this for debugging purposes, cause i'm running a bunch of stories with runStoriesAsPaths and with multiple threads, and I'm trying to log which thread is running which story.
Is there a way to do this?
first you need to create a new StoryReporter (extend that class). In that class you can add actions to be performed before/after story/scenario/step, and you have the story name.
example:
public class NewStoryReporter implements StoryReporter {
private StoryReporter delegate;
public NewStoryReporter(StoryReporter delegate) {
this.delegate = delegate;
}
#Override
public void beforeStory(Story story, boolean givenStory) {
delegate.beforeStory(story, givenStory);
}
#Override
public void beforeScenario(String scenarioTitle) {
delegate.beforeScenario(scenarioTitle);
}
#Override
public void beforeStep(String step) {
if(step.equals("When after each step")){
return;
}
delegate.beforeStep(step);
}
then you need to extend StoryReporterBuilder, this creates your NewStoryReporter.
example:
public class NewStoryReporterBuilder extends StoryReporterBuilder {
#Override
public StoryReporter build(String storyPath) {
StoryReporter delegate = super.build(storyPath);
return new NewStoryReporter(delegate);
}
}
then in your configuration, create an instance of the NewStoryReporterBuilder, and use it in
Configuration configuration = new YourConfiguration().useStoryReporterBuilder(newStoryReporterBuilder....)
Now in Jbehave it's configured in different way.
So, to achieve that goal you need to:
Create new class which extends org.jbehave.core.reporters.ConsoleOutput. Here you can modify various of methods. In your case - you need to override method:
public void beforeScenario(String title)
Check example attached in the end of this post to see how it can be done.
Create new instance of abstract class org.jbehave.core.reporters.Filter:
public static final Format YOUR_CUSTOM_CONSOLE = new Format("YOUR_CUSTOM_CONSOLE")
{
#Override
public StoryReporter createStoryReporter(FilePrintStreamFactory factory,
StoryReporterBuilder storyReporterBuilder) {
return new TeamCityConsoleOutput(storyReporterBuilder.keywords()).doReportFailureTrace(
storyReporterBuilder.reportFailureTrace()).doCompressFailureTrace(
storyReporterBuilder.compressFailureTrace());
}
};
Then you need to add this format to your story builder which you are using in your configuration, that mean:
new MostUsefulConfiguration()
.useStoryReporterBuilder(
new StoryReporterBuilder()
....//here are another modifications of sorey report builder
.withFormats(YOUR_CUSTOM_CONSOLE , .../* another formats */ HTML, Format.XML, Format.TXT))
....//here are another modifications of configuration
.useStepMonitor(new CrossReference().getStepMonitor());
Here is example of such modification, which can be used to integration with TeamCity:
https://github.com/jbehave/jbehave-core/blob/d15774bf763875662869cdc89ce924b1086af6f8/jbehave-core/src/main/java/org/jbehave/core/reporters/TeamCityConsoleOutput.java

How to access XSSAPI from custom jsp Java class?

I am creating a custom tag library using http://www.cqblueprints.com/xwiki/bin/view/Blue+Prints/Writing+A+JSP+Custom+Tag+Library to produce XSS-proof links from my custom components. I have taken this to a tag since I will need to do other bits of work and to avoid writing scriptlets on the JSP files (I have posted the code at the end).
I wanted to use the XSSAPI from my Java class, but looking at the javadoc for XSSAPI I see that it's an interface; when using it in a JSP file it's an object that is initialized invoking <cq:defineObjects/>.
Does anyone have any ideas on how to do this? There is a method in the XSSAPI class called getRequestSpecificAPI(slingRequest) but it's not static, and I have run out of ideas right now.
#JspTag
public class FixInternalLinkTag extends CqSimpleTagSupport {
private String pathToPage;
#Override
public void doTag() throws JspException, IOException {
XSSAPI xssAPI; // ToDo how to get a reference to this?
urlPointingToPage = xssAPI.getValidHref(urlPointingToPage);
getJspWriter().write(urlPointingToPage);
}
public String getPathToPage() {
return pathToPage;
}
#JspTagAttribute(required = true, rtexprvalue = true)
public void setPathToPage(String pathToPage) {
this.pathToPage = pathToPage;
}
}
If you make your tag class an osgi service
#Component(immediate = true, metatype = true, description = "User Group Finder")
#Service
public class MyClass { ...
you can then use
#Reference
XSSAPI xssapi;
to pull in the implementation of XSSAPI. Then you can use it
xssapi.getRequestSpecificAPI(slingRequest);

Setting data to view in GWT MVP

I have a GWT application where MVP pattern is followed.
We have multiple views to show data on UI.
We set the data to view via Activity. Something like this
public class SomeActivityImpl extends AbstractActivity implements SomeView.Presenter {
public SomeActivityImpl{
//some initialization goes here.
}
public void start(AcceptsOneWidget containerWidget, EventBus eventBus) {
//presenter is set here
loadDetails();
}
private void loadDetails(){
SomeRequestFactory.context().findSomeEntity().fire(new Receiver<SomeProxy>() {
#Override
public void onSuccess(SomeProxy proxyObject) {
someView.setName("name");
someview.setSurname("surname");
someview.setMothersName("mothers name");
}
)
}
Now my question is how can I make sure that all the setters of View are set and nothing is missed?
Is there any solution which is GWT specific or can someone suggest a design pattern?
You should use the editor framework. It has a Request Factory driver to help you use it with request Factory. Here's a good tutorial
If you don't like that tutorial, consider looking at GWT in action

Connecting gwt-dispatch with guice and mvp4g

I have some questions regarding gwt-dispatch and guice. I'm using Guice 2.0, gwt-dispatch 1.1.0 snapshot, mvp4g 1.1.0 and GIN 1.0
First of all, I have defined simple action, result and handler:
ListContactsAction.java
public class ListContactsAction implements Action<ListContactsResult>{
public ListContactsAction() {
}
}
ListContactsResult.java
public class ListContactsResult implements Result {
private List<Contact> contactList;
public ListContactsResult() {
}
public ListContactsResult(List<Contact> contactList) {
this.contactList = contactList;
}
public List<Contact> getContactList() {
return contactList;
}
}
ListContactsHandler.java
public class ListContactsHandler implements ActionHandler<ListContactsAction, ListContactsResult>{
#Inject
private SqlSessionFactory factory;
public Class<ListContactsAction> getActionType() {
return ListContactsAction.class;
}
public ListContactsResult execute(ListContactsAction a, ExecutionContext ec) throws DispatchException {
// some code using SqlSessionFactory and returning ListContactResult
// with list of contacts
}
public void rollback(ListContactsAction a, ListContactsResult r, ExecutionContext ec) throws DispatchException {
/* get action - no rollback needed */
}
}
In previous version of my app, which was using rpc service instead of command pattern, I had a method which was providing SqlSessionFactory for injections, something like this:
#Provides
public SqlSessionFactory getSqlSessionFactory(){
// some code here
}
I read on gwt-dispatch getting started that I have to provide binding between my action and it's handler, which should look something like that:
public class ContactModule extends ActionHandlerModule{
#Override
protected void configureHandlers() {
bindHandler(ListContactsAction.class, ListContactsHandler.class);
}
}
But I have problem wiring it all with Guice, because this example from gwt-dispatch site:
public class DispatchServletModule extends ServletModule {
#Override
public void configureServlets() {
serve( "/path/to/dispatch" ).with( DispatchServiceServlet.class );
}
}
doesn't work, since there is no DispatchServiceServlet in the package.
My questions are:
How should I write DispatchServletModule and how to make it going (with what I should serve path)
what should I put in the web.xml file of my app to be able to correctly execute actions from my presenter, which has GIN injected DispatcherAsync implementation
Where should I put my SqlSessionFactory providing method (in which module) to be able to inject SqlSessionFactory where I need it
How I instantiate the injector so then I can use it in other action handlers properly
I think that is all and I made myself clear. If something isn't clear enough, I'll try to be more specific.
Have you created a GuiceServletConfig class? This is where you setup your Dispatch servlet module as well as your action handler module with Guice.
plubic class GuiceServletConfig extends GuiceServletContextListener {
#Override
protected Injector getInjector() {
return Guice.createInjector(new HandlerModule(), new DispatchServletModule());
}
}
The HandlerModule is your ActionHandler module class, so from your code you would put your ContactModule class.
For your SqlSessionFactory, you could setup the binding for it in your ContactModule, with my code I only have a single ServerModule that sets up all my service and action handler bindings. This is mainly for the sake of simplicity.
GWT-Platform framework uses a gwt-dispatch fork to handle rpc requests. There's a lot of code, which you probably had to wtite yourself, if you think of seriously using dispatcher and Guice. I highly recommend it.
Firstly, I sympathise. Putting this all together isn't documented in any one spot. I'll answer each of your questions in turn. Add comments to my answer if any of it is unclear.
QU: How should I write DispatchServletModule and how to make it going (with what I should serve path)?
There's a GuiceStandardDispatchServlet class in the net.customware.gwt.dispatch.server.guice package; use that. I'm not 100 percent sure why, but the path I use includes the name of my GWT module, followed by '/dispatch'. You might have to experiment with that.
public class MyServletModule extends ServletModule {
#Override protected void configureServlets() {
serve("/com.my.module.name/dispatch")
.with(GuiceStandardDispatchServlet.class);
}
}
QU: what should I put in the web.xml file of my app to be able to correctly execute actions from my presenter, which has GIN injected DispatcherAsync implementation?
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<filter>
<filter-name>guiceFilter</filter-name>
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>com.myapp.whatever.MyContextListener</listener-class>
</listener>
...
</web-app>
... and then you'll need a custom context listener that creates a Guice injector as follows. Notice that I've included your ContactModule, which binds action handlers.
public class MyContextListener extends GuiceServletContextListener {
#Override protected Injector getInjector() {
return Guice.createInjector(new MyServletModule(),
new ContactModule(), new SQLStuffModule());
}
}
QU: Where should I put my SqlSessionFactory providing method (in which module) to be able to inject SqlSessionFactory where I need it?
Notice that I included a new SQLStuffModule in the previous code snippet; that would be a good place to put your SqlSessionFactory binding. There's no harm having multiple modules, and I find that it keeps the various concerns nicely separated.
QU: How I instantiate the injector so then I can use it in other action handlers properly?
For the server-side, see the MyContextListener code snippet above.
On the client side, you'll need a custom injector interface something like this:
#GinModules(StandardDispatchModule.class, MyClientModule.class)
public interface MyGinjector extends Ginjector {
MyWidgetMainPanel getMainPanel();
}
...and you can bind your MVP stuff in a custom Gin module as follows. I'm sorry that I'm not familiar with mvp4g, but I assume that you'll need to wire the views and presenters together in the module class.
public class MyClientModule extends AbstractGinModule {
#Override protected void configure() {
bind(...).to(...);
...
}
}