I am using gwt-platform for my application development.
I opened 2 browsers running the same application, i did 2 same operations with different data, but the now the browsers on the same view accessing the similar handler action
now the issue is the 2 browsers has updated with first received data from handler..
i am not understanding why it is not recognized the browsers which send the request... so this means its not Threadsafe...?
I seen #RequestedScope annotation in the Guice is it useful when i use on execute() of Handler
any suggestions?
Thanks in advance...
Maybe...
You have to made your Actions thread-safe. (attrs has final, e.g., inject in constructor), and perharps your logic has to be thread-safe too.
Btw, can you post a example of your action?
With 2 browsers you should have 2 different instances of your app running. In your onModuleLoad(), just put a System.out.println(this);. You should see different result which means you have different instances.
If you run an action from Browser 1, the action will be executed only in Browser 1. I don't know what your action is doing but if it updates data in the datastore (or DB) and since both instances share the persistence layer, you will see the new data in Browser 2 too.
It's very unlikely that the action triggered in Browser 1 is executed on both Browsers. It would mean that they share the same event bus.
public class InfoAction extends UnsecuredActionImpl<Response<ObjectTO>>
{
private List<OpenTO> request;
private String machineId;
private int actionType;
private UserBean userBean;
/**
* This is been in the case of double dated flight.
*/
private String orignalFpesLegId;
public List<OpenTO> getRequest() {
return request;
}
public void setRequest(List<OpenTO> request) {
this.request = request;
}
public String getMachineId() {
return machineId;
}
public void setMachineId(String machineId) {
this.machineId = machineId;
}
/**
* #return the actionType
*/
public int getActionType() {
return actionType;
}
/**
* #param actionType the actionType to set
*/
public void setActionType(int actionType) {
this.actionType = actionType;
}
/**
* #param userBean the userBean to set
*/
public void setUserBean(UserBean userBean) {
this.userBean = userBean;
}
/**
* #return the userBean
*/
public UserBean getUserBean() {
return userBean;
}
}
Please find my action class code
Related
I have 2 different extension. I want to execute second controller (external) inside my first controller
Two different extension 1. Course , 2. Search
class CourseController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController {
/**
* courseRepository
*
* #var \TYPO3\Courses\Domain\Repository\CourseRepository
* #inject
*/
protected $courseRepository = NULL;
/**
* action list
*
* #return void
*/
public function listAction() {
/** I want to access Search extension Controller (f.e searchRepository->listAction() )**/
}
}
class SearchRepository extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController {
/**
* searchRepository
*
* #var \TYPO3\Courses\Domain\Repository\SearchRepository
* #inject
*/
protected $searchRepository = NULL;
/**
* action list
*
* #return void
*/
public function listAction() {
$searches = $this->searchRepository->findAll();
$this->view->assign('searches', $searches);
}
}
tl;dr:
Within a Controller, you usually forward() or redirect() to delegate to a different ControllerAction, e.g. delegate to SearchController::listAction() of 'myExtensionKey':
$this->forward('list', 'Search', 'myExtensionKey');
or
$this->redirect('list', 'Search', 'myExtensionKey');
Long version:
Quote from the MVC documentation of Flow which is quite similar to Extbase MVC:
Often, controllers need to defer execution to other controllers or
actions. For that to happen, TYPO3 Flow supports both, internal and
external redirects:
in an internal redirect which is triggered by forward(), the URI does
not change.
in an external redirect, the browser receives a HTTP
Location header, redirecting him to the new controller. Thus, the URI
changes.
The APIs are:
public void forward(string $actionName, string $controllerName=NULL, string $extensionName=NULL, array $arguments=NULL)
protected void redirect(string $actionName, string $controllerName=NULL, string $extensionName=NULL, array $arguments=NULL, integer $pageUid=NULL, int $delay=0, int $statusCode=303)
The programming API details can be found in the Extbase API
I am having a strange problem with a custom jpa-entity listener I've created in a spring boot application. I'm trying to use Springs #Configurable mechanism to configure the EntityListener (as seen in Springs AuditingEntityListener) but Spring refuses to recognize my Listener as soon as it is used in the #EntityListeners-Annotation on a jpa entity. if it is not configured on a jpa entity, the Listener gets wired/configured by Spring as it should.
I've created an example project with a junit-test to demonstrate the problem:
https://github.com/chrisi/aopconfig/find/master
#SpringBootApplication
#EnableSpringConfigured
#EnableLoadTimeWeaving
public class Application {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}
The EntityListener:
/**
* This bean will NOT be instanciated by Spring but it should be configured by Spring
* because of the {#link Configurable}-Annotation.
* <p>
* The configuration only works if the <code>UnmanagedBean</code> is not used as an <code>EntityListener</code>
* via the {#link javax.persistence.EntityListeners}-Annotation.
*
* #see FooEntity
*/
#Configurable
public class UnmanagedBean {
#Autowired
private ManagedBean bean;
public int getValue() {
return bean.getValue();
}
}
The Bean I want to be injected in the EntityListener/UnmanagedBean:
/**
* This bean will be instanciated/managed by Spring and will be injected into the
* {#link UnmanagedBean} in the case the <code>UnmanagedBean</code> is not used as an JPA-EntityListener.
*/
#Component
#Data
public class ManagedBean {
private int value = 42;
}
The Entity where the Listener should be used:
/**
* This simple entity's only purpose is to demonstrate that as soon as
* it is annotated with <code>#EntityListeners({UnmanagedBean.class})</code>
* springs configurable mechanism will not longer work on the {#link UnmanagedBean}
* and therefore the <code>ConfigurableTest.testConfigureUnmanagedBean()</code> fails.
*/
#Entity
#EntityListeners({UnmanagedBean.class}) // uncomment to make the test fail
public class FooEntity {
#Id
private Long id;
private String bar;
}
And finally the test that shows that the wiring is not working as soon as the Listener is used:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = Application.class)
public class ConfigurableTest {
/**
* This test checks if the ManagedBean was injected into the UnmanagedBean
* by Spring after it was created with <code>new</code>
*/
#Test
public void testConfigureUnmanagedBean() {
UnmanagedBean edo = new UnmanagedBean();
int val = edo.getValue();
Assert.assertEquals(42, val);
}
}
The junit-test (the wiring of the EntityListener/ManagedBean) fails as soon as
the annotation #EntityListeners({UnmanagedBean.class}) in FooEntity is activated.
Is this a bug or did I miss something else?
In order to run the test you have to use -javaagent:spring-instrument-4.1.6.RELEASE.jar on the commandline an provide the jar file in the working directory.
This is the "condensed" version of a question I asked earlier:
#Configurable not recognized in SpringBoot Application
I am building a Java application on the Equinox OSGi framework and I have been using DS (declarative services) to declare referenced and provided services. So far all the service consumers I have implemented happened to be service providers as well, so it was natural for me to make them stateless (so that they can be reused by multiple consumers, rather than being attached to one consumer) and let them be instantiated by the framework (default constructor, invoked nowhere in my code).
Now I have a different situation: I have a class MyClass that references a service MyService but is not itself a service provider. I need to be able to instantiate MyClass myself, rather than letting the OSGi framework instantiate it. I would then want the framework to pass the existing MyService instance to the MyClass instance(s). Something like this:
public class MyClass {
private String myString;
private int myInt;
private MyService myService;
public MyClass(String myString, int myInt) {
this.myString = myString;
this.myInt= myInt;
}
// bind
private void setMyService(MyService myService) {
this.myService = myService;
}
// unbind
private void unsetMyService(MyService myService) {
this.myService = null;
}
public void doStuff() {
if (myService != null) {
myService.doTheStuff();
} else {
// Some fallback mechanism
}
}
}
public class AnotherClass {
public void doSomething(String myString, int myInt) {
MyClass myClass = new MyClass(myString, myInt);
// At this point I would want the OSGi framework to invoke
// the setMyService method of myClass with an instance of
// MyService, if available.
myClass.doStuff();
}
}
My first attempt was to use DS to create a component definition for MyClass and reference MyService from there:
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="My Class">
<implementation class="my.package.MyClass"/>
<reference bind="setMyService" cardinality="0..1" interface="my.other.package.MyService" name="MyService" policy="static" unbind="unsetMyService"/>
</scr:component>
However, MyClass is not really a component, since I don't want its lifecycle to be managed -- I want to take care of instantiation myself. As Neil Bartlett points out here:
For example you could say that your component "depends on" a
particular service, in which case the component will only be created
and activated when that service is available -- and also it will be
destroyed when the service becomes unavailable.
This is not what I want. I want the binding without the lifecycle management.
[Note: Even if I set the cardinality to 0..1 (optional and unary), the framework will still try instantiate MyClass (and fail because of the lack of no-args constructor)]
So, my question: is there a way to use DS to have this "binding-only, no lifecycle management" functionality I'm looking for? If this is not possible with DS, what are the alternatives, and what would you recommend?
Update: use ServiceTracker (suggested by Neil Bartlett)
IMPORTANT: I've posted an improved version of this below as an answer. I'm just keeping this here for "historic" purposes.
I'm not sure how to apply ServiceTracker in this case. Would you use a static registry as shown below?
public class Activator implements BundleActivator {
private ServiceTracker<MyService, MyService> tracker;
#Override
public void start(BundleContext bundleContext) throws Exception {
MyServiceTrackerCustomizer customizer = new MyServiceTrackerCustomizer(bundleContext);
tracker = new ServiceTracker<MyService, MyService>(bundleContext, MyService.class, customizer);
tracker.open();
}
#Override
public void stop(BundleContext bundleContext) throws Exception {
tracker.close();
}
}
public class MyServiceTrackerCustomizer implements ServiceTrackerCustomizer<MyService, MyService> {
private BundleContext bundleContext;
public MyServiceTrackerCustomizer(BundleContext bundleContext) {
this.bundleContext = bundleContext;
}
#Override
public MyService addingService(ServiceReference<MyService> reference) {
MyService myService = bundleContext.getService(reference);
MyServiceRegistry.register(myService); // any better suggestion?
return myService;
}
#Override
public void modifiedService(ServiceReference<MyService> reference, MyService service) {
}
#Override
public void removedService(ServiceReference<MyService> reference, MyService service) {
bundleContext.ungetService(reference);
MyServiceRegistry.unregister(service); // any better suggestion?
}
}
public class MyServiceRegistry {
// I'm not sure about using a Set here... What if the MyService instances
// don't have proper equals and hashCode methods? But I need some way to
// compare services in isActive(MyService). Should I just express this
// need to implement equals and hashCode in the javadoc of the MyService
// interface? And if MyService is not defined by me, but is 3rd-party?
private static Set<MyService> myServices = new HashSet<MyService>();
public static void register(MyService service) {
myServices.add(service);
}
public static void unregister(MyService service) {
myServices.remove(service);
}
public static MyService getService() {
// Return whatever service the iterator returns first.
for (MyService service : myServices) {
return service;
}
return null;
}
public static boolean isActive(MyService service) {
return myServices.contains(service);
}
}
public class MyClass {
private String myString;
private int myInt;
private MyService myService;
public MyClass(String myString, int myInt) {
this.myString = myString;
this.myInt= myInt;
}
public void doStuff() {
// There's a race condition here: what if the service becomes
// inactive after I get it?
MyService myService = getMyService();
if (myService != null) {
myService.doTheStuff();
} else {
// Some fallback mechanism
}
}
protected MyService getMyService() {
if (myService != null && !MyServiceRegistry.isActive(myService)) {
myService = null;
}
if (myService == null) {
myService = MyServiceRegistry.getService();
}
return myService;
}
}
Is this how you would do it?
And could you comment on the questions I wrote in the comments above? That is:
Problems with Set if the service implementations don't properly implement equals and hashCode.
Race condition: the service may become inactive after my isActive check.
No this falls outside the scope of DS. If you want to directly instantiate the class yourself then you will have to use OSGi APIs like ServiceTracker to obtain the service references.
Update:
See the following suggested code. Obviously there are a lot of different ways to do this, depending on what you actually want to achieve.
public interface MyServiceProvider {
MyService getService();
}
...
public class MyClass {
private final MyServiceProvider serviceProvider;
public MyClass(MyServiceProvider serviceProvider) {
this.serviceProvider = serviceProvider;
}
void doStuff() {
MyService service = serviceProvider.getService();
if (service != null) {
// do stuff with service
}
}
}
...
public class ExampleActivator implements BundleActivator {
private MyServiceTracker tracker;
static class MyServiceTracker extends ServiceTracker<MyService,MyService> implements MyServiceProvider {
public MyServiceTracker(BundleContext context) {
super(context, MyService.class, null);
}
};
#Override
public void start(BundleContext context) throws Exception {
tracker = new MyServiceTracker(context);
tracker.open();
MyClass myClass = new MyClass(tracker);
// whatever you wanted to do with myClass
}
#Override
public void stop(BundleContext context) throws Exception {
tracker.close();
}
}
Solution: use ServiceTracker (as suggested by Neil Bartlett)
Note: if you want to see the reason for the downvote please see Neil's answer and our back-and-forth in its comments.
In the end I've solved it using ServiceTracker and a static registry (MyServiceRegistry), as shown below.
public class Activator implements BundleActivator {
private ServiceTracker<MyService, MyService> tracker;
#Override
public void start(BundleContext bundleContext) throws Exception {
MyServiceTrackerCustomizer customizer = new MyServiceTrackerCustomizer(bundleContext);
tracker = new ServiceTracker<MyService, MyService>(bundleContext, MyService.class, customizer);
tracker.open();
}
#Override
public void stop(BundleContext bundleContext) throws Exception {
tracker.close();
}
}
public class MyServiceTrackerCustomizer implements ServiceTrackerCustomizer<MyService, MyService> {
private BundleContext bundleContext;
public MyServiceTrackerCustomizer(BundleContext bundleContext) {
this.bundleContext = bundleContext;
}
#Override
public MyService addingService(ServiceReference<MyService> reference) {
MyService myService = bundleContext.getService(reference);
MyServiceRegistry.getInstance().register(myService);
return myService;
}
#Override
public void modifiedService(ServiceReference<MyService> reference, MyService service) {
}
#Override
public void removedService(ServiceReference<MyService> reference, MyService service) {
bundleContext.ungetService(reference);
MyServiceRegistry.getInstance().unregister(service);
}
}
/**
* A registry for services of type {#code <S>}.
*
* #param <S> Type of the services registered in this {#code ServiceRegistry}.<br>
* <strong>Important:</strong> implementations of {#code <S>} must implement
* {#link #equals(Object)} and {#link #hashCode()}
*/
public interface ServiceRegistry<S> {
/**
* Register service {#code service}.<br>
* If the service is already registered this method has no effect.
*
* #param service the service to register
*/
void register(S service);
/**
* Unregister service {#code service}.<br>
* If the service is not currently registered this method has no effect.
*
* #param service the service to unregister
*/
void unregister(S service);
/**
* Get an arbitrary service registered in the registry, or {#code null} if none are available.
* <p/>
* <strong>Important:</strong> note that a service may become inactive <i>after</i> it has been retrieved
* from the registry. To check whether a service is still active, use {#link #isActive(Object)}. Better
* still, if possible don't store a reference to the service but rather ask for a new one every time you
* need to use the service. Of course, the service may still become inactive between its retrieval from
* the registry and its use, but the likelihood of this is reduced and this way we also avoid holding
* references to inactive services, which would prevent them from being garbage-collected.
*
* #return an arbitrary service registered in the registry, or {#code null} if none are available.
*/
S getService();
/**
* Is {#code service} currently active (i.e., running, available for use)?
* <p/>
* <strong>Important:</strong> it is recommended <em>not</em> to store references to services, but rather
* to get a new one from the registry every time the service is needed -- please read more details in
* {#link #getService()}.
*
* #param service the service to check
* #return {#code true} if {#code service} is currently active; {#code false} otherwise
*/
boolean isActive(S service);
}
/**
* Implementation of {#link ServiceRegistry}.
*/
public class ServiceRegistryImpl<S> implements ServiceRegistry<S> {
/**
* Services that are currently registered.<br>
* <strong>Important:</strong> as noted in {#link ServiceRegistry}, implementations of {#code <S>} must
* implement {#link #equals(Object)} and {#link #hashCode()}; otherwise the {#link Set} will not work
* properly.
*/
private Set<S> myServices = new HashSet<S>();
#Override
public void register(S service) {
myServices.add(service);
}
#Override
public void unregister(S service) {
myServices.remove(service);
}
#Override
public S getService() {
// Return whatever service the iterator returns first.
for (S service : myServices) {
return service;
}
return null;
}
#Override
public boolean isActive(S service) {
return myServices.contains(service);
}
}
public class MyServiceRegistry extends ServiceRegistryImpl<MyService> {
private static final MyServiceRegistry instance = new MyServiceRegistry();
private MyServiceRegistry() {
// Singleton
}
public static MyServiceRegistry getInstance() {
return instance;
}
}
public class MyClass {
private String myString;
private int myInt;
public MyClass(String myString, int myInt) {
this.myString = myString;
this.myInt= myInt;
}
public void doStuff() {
MyService myService = MyServiceRegistry.getInstance().getService();
if (myService != null) {
myService.doTheStuff();
} else {
// Some fallback mechanism
}
}
}
If anyone wants to use this code for whatever purpose, go ahead.
I have a little problem with a list that contains different types of elements and i would like to see if anyone of you have met the problem before. The issue should be solved with the use of #ExtraTypes, but it is not working for me, so i guess i am not using it correctly. So, the scenario is (bean names are changed for clarity):
GENERAL:
I am using GWT 2.5 with RequestFactory.
SERVER-SIDE:
I have a RootBean that contains, among other stuff, a List <ChildBean>.
This ChildBean contains some primitive attributes.
ChildBean is also extended by a MoreSpecificChildBean that inherits all the parent attributes and adds a few more.
The RootBean gets its list filled up with elements of type ChildBean and MoreSpecificChildBean depending on some logic.
CLIENT-SIDE:
IRootBeanProxy is a ValueProxy with these annotations:
#ProxyFor (value = RootBean.class)
#ExtraTypes ({IMoreSpecificChildBeanProxy.class})
and contains a list
List <IChildBeanProxy> getChildren ();
IChildBeanProxy is a ValueProxy:
#ProxyFor (value=ChildBean)
public interface IChildBeanProxy extends ValueProxy
IMoreSpecificChildBeanProxy is a ValueProxy:
#ProxyFor (value=MoreSpecificChildBean)
public interface IMoreSpecificChildBeanProxy extends IChildBeanProxy
the Request context has a method that returns Request and i added the #ExtraTypes annotation here too:
#Service (value = CompareService.class, locator = SpringServiceLocator.class)
#ExtraTypes ({IChildBeanProxy.class, IMoreSpecificChildBeanProxy.class})
public interface ICompareRequestContext extends RequestContext {
Request <IRootBeanProxy> compare (Integer id1, Integer id2);
Question
Supposedly with those annotations, RF should be aware of the existence of polymorphic inherited classes, but all i get in the client is an IRootBeanProxy with a list of IChildBeanProxy elements. This list includes the MoreSpecificChildBean, but in the shape of a IChildBeanProxy, so that i cannot tell it from the others.
So i am wondering what i am doing wrong, if i am setting the ExtraTypes annotation at the wrong place or something.
Anyone?
Thx for all the help!!
I do the exact same thing for quite a few classes but it will always return me the base type which I can iterate through and test for instanceof if needed. You will probably have to cast the object to the subclass. If you do not add the #ExtraTypes you will know because on the server side you will get a message stating that MoreSpecificChildBean cannot be sent to the client.
I only annotate the service and not the proxy, I ran into some quirks with 2.4 adding #ExtraTypes to the proxy.
/**
* Base proxy that all other metric proxies extend. It is used mainly for it's
* inheritence with the RequestFactory. It's concrete implementation is
* {#link MetricNumber}.
*
* #author chinshaw
*/
#ProxyFor(value = Metric.class, locator = IMetricEntityLocator.class)
public interface MetricProxy extends DatastoreObjectProxy {
/**
* Name of this object in the ui. This will commonly be extended by
* subclasses.
*/
public String NAME = "Generic Metric";
/**
* This is a list of types of outputs that the ui can support. This is
* typically used for listing types of supported Metrics in the operation
* output screen.
*
* #author chinshaw
*/
public enum MetricOutputType {
MetricNumber, MetricString, MetricCollection, MetricStaticChart, MetricDynamicChart
}
/**
* See {#link MetricNumber#setName(String)}
*
* #param name
*/
public void setName(String name);
/**
* See {#link MetricNumber#setContext(String)}
*
* #return name of the metric.
*/
public String getName();
/**
* Get the list of violations attached to this metric.
*
* #return
*/
public List<ViolationProxy> getViolations();
}
#ProxyFor(value = MetricNumber.class, locator = IMetricEntityLocator.class)
public interface MetricNumberProxy extends MetricProxy {
public List<NumberRangeProxy> getRanges();
public void setRanges(List<NumberRangeProxy> ranges);
}
...
#ProxyFor(value = MetricDouble.class, locator = IMetricEntityLocator.class)
public interface MetricDoubleProxy extends MetricNumberProxy {
/* Properties when fetching the object for with clause */
public static String[] PROPERTIES = {"ranges"};
public Double getValue();
}
...
#ProxyFor(value = MetricPlot.class, locator = IMetricEntityLocator.class)
public interface MetricPlotProxy extends MetricProxy {
/**
* UI Name of the object.
*/
public String NAME = "Static Plot";
public String getPlotUrl();
}
This is a made up method from because I usually always return composite classes that may contain a list of metrics. That being said this will return me the base type of metrics, and then I can cast them.
#ExtraTypes({ MetricProxy.class, MetricNumberProxy.class, MetricDoubleProxy.class, MetricIntegerProxy.class})
#Service(value = AnalyticsOperationDao.class, locator = DaoServiceLocator.class)
public interface AnalyticsOperationRequest extends DaoRequest<AnalyticsOperationProxy> {
Request<List<<MetricProxy>> getSomeMetrics();
}
Not an exact method I use but will work for getting a proxy of type.
context.getSomeMetrics().with(MetricNumber.PROPERTIES).fire(new Receiver<List<MetricProxy>>() {
public void onSuccess(List<MetricProxy> metrics) {
for (MetricProxy metric : metrics) {
if (metric instanceof MetricDoubleProxy) {
logger.info("Got a class of double " + metric.getValue());
}
}
}
}
You will know if you are missing an #ExtraTypes annotation when you get the error stated above.
Hope that helps
I am unable to serialize an Enum to GWT if it implements java.io.Serializable. It will GWT compile successfully, but at runtime, I get the dreaded:
Type 'com....security..AdminPrivilege' was not assignable to 'com.google.gwt.user.client.rpc.IsSerializable' and did not have a custom field serializer.For security purposes, this type will not be serialized.: instance = Login to Console
If I implement com.google.gwt.user.client.rpc.IsSerializable it compiles and runs fine. I am trying to avoid IsSerializable, since this Enum is persisted in our DB and is referenced in non-GWT servlets. I do not want to introduce a GWT dependancy, even for that single class.
I've read most of the discussions on this topic here. I have:
added a serialVersionUid (which should not be necessary)
added a no-arg constructor (but this is an Enum, so it must be private - I suspect this may be the problem)
added a callable RPC method that returns the Enum and takes a Set of the Enum as an input argument (trying to get this Enum into the whitelist) -
For all other Enums, I generated a GWT version which implements IsSerializable. But this new Enum is too complex to generate and I need the methods from the Enum in the GWT code.
Thanks for any help on this.
My Enum is below. Notice it has an embedded Enum:
public enum AdminPrivilege implements java.io.Serializable {
// Privileges
MANAGE_XX("Manage XX", PrivilegeCategory.XX),
IMPORT_LICENSE("Import a License", PrivilegeCategory.XX),
SUBMIT_BUG("Submit a Bug", PrivilegeCategory.XX),
TEST_AD("Test AD", PrivilegeCategory.XX),
// Administrator Privileges
LOGIN("Login to XX", PrivilegeCategory.ADMIN),
MANAGE_ADMIN("Manage Administrators", PrivilegeCategory.ADMIN),
MANAGE_ROLE("Manage Roles", PrivilegeCategory.ADMIN),
// Task Privileges
CANCEL_TASK("Cancel Tasks", PrivilegeCategory.TASK), ;
private static final long serialVersionUID = 1L;
/**
* Defines the privilege categories.
*
*/
public enum PrivilegeCategory implements java.io.Serializable {
XX("XX"),
ADMIN("Administrator"),
TASK("Task"), ;
private static final long serialVersionUID = 2L;
private String displayValue;
// This constructor is required for GWT serialization
private PrivilegeCategory() {
}
private PrivilegeCategory(String displayValue) {
this.displayValue = displayValue;
}
#Override
public String toString() {
return displayValue;
}
}
private String displayValue;
private AdminPrivilege parentPrivilege;
private PrivilegeCategory privilegeCategory;
// This constructor is required for GWT serialization
private AdminPrivilege() {
}
private AdminPrivilege(String displayValue, PrivilegeCategory category) {
this.displayValue = displayValue;
this.privilegeCategory = category;
}
private AdminPrivilege(String displayValue, PrivilegeCategory category, AdminPrivilege parent) {
this(displayValue, category);
this.parentPrivilege = parent;
}
/**
* Return the parent privilege for this privilege.
*
* #return
*/
public AdminPrivilege getParentPrivilege() {
return parentPrivilege;
}
/**
* Return the category for this privilege.
*
* #return
*/
public PrivilegeCategory getPrivilegeCategory() {
return privilegeCategory;
}
/**
* Return the set of categories.
*
* #return
*/
public static Set<PrivilegeCategory> getPrivilegeCategories() {
Set<PrivilegeCategory> category = new HashSet<PrivilegeCategory>();
for (PrivilegeCategory c : PrivilegeCategory.values()) {
category.add(c);
}
return category;
}
/**
* Return the set of privileges for a category.
*
* #return
*/
public static Set<AdminPrivilege> getPrivileges(PrivilegeCategory category) {
Set<AdminPrivilege> privileges = new HashSet<AdminPrivilege>();
for (AdminPrivilege p : AdminPrivilege.values()) {
if (category.equals(p.getPrivilegeCategory())) {
privileges.add(p);
}
}
return privileges;
}
/**
* Return the set of child privileges for a specific privilege
*
* #param parent
* #return
*/
public static Set<AdminPrivilege> getChildPrivileges(AdminPrivilege parent) {
Set<AdminPrivilege> children = new HashSet<AdminPrivilege>();
for (AdminPrivilege priv : values()) {
if (parent.equals(priv.getParentPrivilege())) {
children.add(priv);
}
}
return children;
}
/**
* Return the set of privileges that are parent privileges
*
* #return
*/
public static Set<AdminPrivilege> getParentPrivileges() {
Set<AdminPrivilege> parents = new HashSet<AdminPrivilege>();
for (AdminPrivilege priv : values()) {
if (priv.getParentPrivilege() == null) {
parents.add(priv);
}
}
return parents;
}
}
}
Have you specified a parameterized constructor in your enum? If you have, and it has parameters, you need to remember to add a no-parameters constructor as well, even if you don't use it, because GWT will need it. Adding a parameterized constructor and forgetting to add a parameterless one gets me every time, at least with non-enum classes.