I'm using Wicket 7 and extending AuthenticatedWebSession as a class called BasicAuthenticatedSession. While I'm doing this, I'd like to add a method that returns some additional information about the authenticated user.
In BasicAuthenticatedSession#authenticate, I get a Sysuser object which is a wrapper for a user in the database. I use some of the information in this object for the authentication, but want to have access to all of the info (firstname, lastname, etc.) throughout the session.
I was expecting to be able to create a new method call getUser which would return this database object to the caller.
However, this method, even though declared public, isn't visible when attempting to call it. I'm not sure if this is something to do with Wicket, or just a general misunderstanding on my part how inheritance works. ;)
BasicAuthenticatedWebSession.java
public class BasicAuthenticatedWebSession extends AuthenticatedWebSession {
public BasicAuthenticatedWebSession(Request request) {
super(request);
}
#Override
protected boolean authenticate(String username, String password) {
Sysuser[] sysusers;
try {
SysuserCriteria userCriteria = new SysuserCriteria();
userCriteria.username.eq(username);
sysusers = Sysuser.listSysuserByCriteria(userCriteria);
} catch (PersistentException e) {
e.printStackTrace();
return false;
}
if (sysusers.length == 0) {
return false;
}
this.username = username;
this.userid = sysusers[0].getId();
return password.compareTo(sysusers[0].getPasswd()) == 0;
}
public Roles getRoles() {
Roles roles = new Roles();
Sysuser[] sysusers;
if (isSignedIn()) {
roles.add("SIGNED_IN");
}
try {
SysuserCriteria sysuserCriteria = new SysuserCriteria();
sysuserCriteria.username.eq(username);
sysusers = Sysuser.listSysuserByCriteria(sysuserCriteria);
for (Object sysuser : sysusers) {
SysroleSetCollection sysroles = ((Sysuser) sysuser).sysrole;
for (Sysrole sysrole : sysroles.toArray()) {
roles.add(sysrole.getRolename().toUpperCase());
}
}
} catch (PersistentException e) {
e.printStackTrace();
}
return roles;
}
public Sysuser getSysuser() {
return sysuser;
}
}
Test.java This class fails to compile as the getSysuser method in BasicAuthenticatedSession is not found.
public class Test {
public Test() {
}
public void foo {
if(BasicAuthenticatedSession.get().isSignedIn()) {
Sysuser sysUser = BasicAuthenticatedSession.get().getSysuser();
System.out.println(sysuser.getFirstname);
}
}
}
Wicket project require specific "override" of static methods, I guess that You return original wicket API session. Edited copy from my project (session is Your classname)
public class BasicAuthenticatedWebSession extends AuthenticatedWebSession {
public static BasicAuthenticatedWebSession get() {
return (BasicAuthenticatedWebSession ) Session.get();
}
...
}
and in XxxxxApplication class
public class MyProject extends AuthenticatedWebApplication
{
...
#Override
public Session newSession(Request request, Response response) {
return new BasicAuthenticatedWebSession (request);
}
}
Related
I am trying to generate a very simple code with Byte Buddy.
I have a POJO class where some fields are annotated with #SecureAttribute, For such fields I would like to override getter implementation and redirect the call to a SecurityService.getSecureValue() implementation.
Original class:
public class Properties {
#SecureAttribute
protected String password;
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
Desired Proxy:
public class PropertiesProxy {
private SecurityService securityService;
public void setSecurityService(SecurityService var1) {
this.securityService = var1;
}
public SecurityService getSecurityService() {
return this.securityService;
}
#Override
public String getPassword() {
return securityService.getSecureValue(password);
}
}
Emitting a field was easy but overriding a method becomes complicated. I have found a number of samples relative to my task which I try to apply but do not seem to get the required result.
So my major question is: how do I trace and debug the code generator? First thing I've learned was to print the class to file:
DynamicType.Unloaded<?> unloadedType = byteBuddy.make();
unloadedType.saveIn(new File("d:/temp/bytebuddy"));
This gives me an output where the extra field was added but not a glance of the getter override (disassembled from .class file):
public class PropertiesImpl$ByteBuddy$OLlyZYNY extends PropertiesImpl {
private SecurityService securityService;
public void setSecurityService(SecurityService var1) {
this.securityService = var1;
}
public SecurityService getSecurityService() {
return this.securityService;
}
public PropertiesImpl$ByteBuddy$OLlyZYNY() {
}
}
Here I do not exactly understand how to look for the error. Does it mean that I used totally wrong method implementation and Byte Buddy simply skipped it? Or am I wrong with ElementMatchers? Is there some trace or whatever that will give me a clue how to fix my code?
Current implementation:
private Class<?> wrapProperties() throws IOException {
DynamicType.Builder<?> byteBuddy = new ByteBuddy()
.subclass(PropertiesImpl.class)
.defineProperty("securityService", SecurityService.class);
Arrays.stream(PropertiesImpl.class.getDeclaredFields())
.filter(item -> item.getAnnotation(SecureAttribute.class) != null)
.forEach(item -> byteBuddy
.method(ElementMatchers.named(getGetterBeanName(item)))
.intercept(new GetterWrapperImplementation(item)));
DynamicType.Unloaded<?> unloadedType = byteBuddy.make();
unloadedType.saveIn(new File("d:/temp/bytebuddy"));
Class<?> wrapperClass = unloadedType.load(PropertiesImpl.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
return wrapperClass;
}
public static class GetterWrapperImplementation implements Implementation {
public static final TypeDescription SS_TYPE;
public static final MethodDescription SS_GET_SECURE_VALUE;
private final Field filed;
static {
try {
SS_TYPE = new TypeDescription.ForLoadedType(SecurityService.class);
SS_GET_SECURE_VALUE = new MethodDescription.ForLoadedMethod(SecurityService.class.getDeclaredMethod("getSecureValue", String.class));
}
catch (final NoSuchMethodException | SecurityException e) {
throw new RuntimeException(e);
}
}
public GetterWrapperImplementation(Field filed) {
this.filed = filed;
}
#Override
public InstrumentedType prepare(final InstrumentedType instrumentedType) {
return instrumentedType;
}
#Override
public ByteCodeAppender appender(final Target implementationTarget) {
final TypeDescription thisType = implementationTarget.getInstrumentedType();
return new ByteCodeAppender.Simple(Arrays.asList(
TypeCreation.of(SS_TYPE),
// get securityService field
MethodVariableAccess.loadThis(),
FieldAccess.forField(thisType.getDeclaredFields()
.filter(ElementMatchers.named("securityService"))
.getOnly()
).read(),
// get secure field
MethodVariableAccess.loadThis(),
FieldAccess.forField(thisType.getDeclaredFields()
.filter(ElementMatchers.named(filed.getName()))
.getOnly()
).read(),
MethodInvocation.invoke(SS_GET_SECURE_VALUE),
MethodReturn.of(TypeDescription.STRING)
));
}
}
What I know for the fact is that breakpoints inside ByteCodeAppender appender(final Target implementationTarget) do not get hit, but again not sure how to interpret this.
Thanks.
The Byte Buddy DSL is immutable. This means that you always have to call:
builder = builder.method(...).intercept(...);
Your forEach does not do what you expect for this reason.
As for your implementation, you can just use MethodCall on a field and define the other field as an argument.
Is it possible to configure custom factories to generate values for the EqualsMethodTester and HashCodeMethodTester classes from org.meanbean.test? When I pass the Configuration which works for BeanTester to EqualsMethodTester, I get the following messages in the error traceback:
org.meanbean.factories.ObjectCreationException: Failed to create a value for property [demoUrl].
Failed to find suitable Factory for property=[demoUrl] of type=[class java.net.URL]. Please register a custom Factory.
org.meanbean.factories.ObjectCreationException: Failed to instantiate object of type [java.net.URL] due to NoSuchMethodException.
java.lang.NoSuchMethodException: java.net.URL.<init>()
(Both EqualsMethodTester and HashCodeMethodTester give this error. Adding "demoUrl" to the list of insignificantProperties for EqualsMethodTester().testEqualsMethod() makes no difference. Stepping through the code implies my URLFactory.create() isn't called at all.)
I do not see any options for passing the configuration into HashCodeMethodTester. I've skimmed documentation at the following sites, but have found neither a solution nor acknowledgement of the missing functionality: http://meanbean.sourceforge.net/docs/2.0.3/public/org/meanbean/test/EqualsMethodTester.html
http://meanbean.sourceforge.net/docs/2.0.3/public/org/meanbean/test/HashCodeMethodTester.html
http://meanbean.sourceforge.net/docs/2.0.3/public/org/meanbean/test/ConfigurationBuilder.html
http://meanbean.sourceforge.net/docs/2.0.3/Mean_Bean_2.0.3_User_Guide.pdf
(I'm using MeanBean v 2.0.3 and Java 1.8.)
I have the following class, using java.net.URL:
public class Product {
private String name;
private URL demoUrl;
public Product(){
super();
}
public int hashCode() {
return Objects.hash(getName(), whitehawkSKU);
}
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
if (obj.getClass() != getClass()) {
return false;
}
Product other = (Product) obj;
return Objects.equals(getName(), other.getName());
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public URL getDemoUrl() {
return demoUrl;
}
public void setDemoUrl(URL demoUrl) {
this.demoUrl = demoUrl;
}
}
To handle the URL field, I created a custom factory, as per meanbean: failed to test bean with arrays and it works for BeanTester but not for EqualsMethodTester:
import org.meanbean.lang.Factory;
import java.net.MalformedURLException;
import java.net.URL;
public class URLFactory implements Factory<URL> {
private static int counter = 0;
#Override
public URL create() {
String host = "http://test." + counter + ".url/";
try {
return new URL(host);
}
catch (MalformedURLException except) {
return null;
}
}
}
My test methods are as follows:
private Configuration configureMeanBeanTests() {
URLFactory urlFactory = new URLFactory();
return new ConfigurationBuilder()
.overrideFactory("demoUrl", urlFactory).build();
}
#Test
public void testAccessors() {
new BeanTester().testBean(Product.class, configureMeanBeanTests());
}
#Test
public void testEquals() {
new EqualsMethodTester().testEqualsMethod(
Product.class,
configureMeanBeanTests(),
"name",
"demoUrl"
);
}
#Test
public void testHashCode() {
new HashCodeMethodTester().testHashCodeMethod(Product.class);
}
What am I missing?
It looks like the EqualsMethodTester().testEqualsMethod() needs a EquivalentFactory in that particular case due to the use java.net.URL that does not provide a default empty constructor. So when BasicNewObjectInstanceFactory.create() is called for java.net.URL the call the clazz.getDeclaredConstructor() throw an exception Method threw 'java.lang.NoSuchMethodException' exception..
Basically you just have to implement a EquivalentFactory.
An anonymous implementation could be:
private EquivalentFactory<Product> productEquivalentFactory = new EquivalentFactory<Product>() {
#Override
public Product create() {
Product p = new Product();
try {
p.setDemoUrl(new URL("http://test.1.url/"));
} catch (MalformedURLException e) {
e.printStackTrace();
}
p.setName("test");
return p;
}
};
It has to be used with the custom configuration that you already have:
new EqualsMethodTester().testEqualsMethod(productEquivalentFactory, configureMeanBeanTests(), "demoUrl");`
For the hashcode just use the equivalent factory and it does the job.
I tested it and it is working.
I'm working on a small project where I want to have a list of a class called "DevelopmentEmployee", but only one of them is allowed to manipulate certain methods in another class "Project". The way I have implemented it, the class Project has a field called projectLeader, which is of the type DevelopmentEmployee. When a DevelopmentEmployee attempts to access methods in the class Project, I want to check if the DevelopmentEmployee is equal to the specific instance of Project's projectLeader.
Something like
public class Project {
private DevelopmentEmployee projectLeader;
private List < Activity > activities = new ArrayList < Activity > ();
public Project(DevelopmentEmployee pL) {
this.projectLeader = pL;
}
public void addActivity(String activityName) {
if (projectLeader.equals(DevelopmentEmployee * ) {
activities.add(activity);
}
}
}
But I can't figure out a way to make the access requirement work. How can the instance of the class Project know who is trying to access it?
You should also pass the DevelopementEmployee in addActivity for checking it against the projectLeader.
public void addActivity(String activityName,DevelopmentEmployee employee) {
if (projectLeader.equals(employee) {
activities.add(activity);
}
}
Then you need to override equals method in DevelopmentEmployee class, for proper checking of equality, like the one as shown below :
public boolean equals(DevelopementEmployee e){
if(e!=null && this.employeeId==e.employeeId)
return true;
else
return false;
}
Several possibilities come to mind:
Provide the instance of the one accassing the project method to the method:
public void addActivity(String activityName, DevelpmentEmployee user) {
if (projectLeader.equals(user)) {`
Create some class that holds information about active user and use that inside the methods:
public class Project {
private UserRegistry userRegistry;
private List<Activity> activities = new ArrayList<Activity>();
public Project(UserRegistry userRegistry) {
this.userRegistry = userRegistry;
}
public void addActivity(String activityName) {
if (userRegistry.isActiveUserProjectLeader()) {
activities.add(activity);
}
}
}
public class UserRegistry {
private DevelpmentEmployee projectLeader;
private DevelpmentEmployee activeUser;
private List<DevelpmentEmployee> user;
public void addUser(DevelpmentEmployee user) { ... }
public void makeProjectLeader(DevelpmentEmployee newLeader) { ... }
public void makeActiveUser(DevelpmentEmployee newActiveUser) { ... }
public boolean isActiveUserProjectLeader() { ... }
}`
I have RESTeasy service. And have implemented simple error handling on methods using try catch and feel something is not very well with it. I've noticed try catch repetition on all my methods. So I want ask way how to avoid repetition (to reduce code size) of try catch but not lost functionality.
#Path("/rest")
#Logged
#Produces("application/json")
public class CounterRestService {
#POST
#Path("/create")
public CounterResponce create(#QueryParam("name") String name) {
try {
CounterService.getInstance().put(name);
return new CounterResponce();
} catch (Exception e){
return new CounterResponce("error", e.getMessage());
}
}
#POST
#Path("/insert")
public CounterResponce create(Counter counter) {
try {
CounterService.getInstance().put(counter);
return new CounterResponce();
} catch (Exception e){
return new CounterResponce("error", e.getMessage());
}
}
#DELETE
#Path("/delete")
public CounterResponce delete(#QueryParam("name") String name) {
try {
CounterService.getInstance().remove(name);
return new CounterResponce();
} catch (Exception e){
return new CounterResponce("error", e.getMessage());
}
}
... // other methods with some try catch pattern
response
public class CounterResponce {
private String status;
#JsonSerialize(include=Inclusion.NON_NULL)
private Object data;
public CounterResponce() {
this.status = "ok";
}
public CounterResponce(Object o) {
this.status = "ok";
this.data = o;
}
public CounterResponce(String status, Object o){
this.status = status;
this.data = o;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
exceptions source
public class CounterService {
private Map<String, StatisticCounter> counters = new HashMap<String, StatisticCounter>();
private static CounterService instance = null;
protected CounterService() {}
public static CounterService getInstance() {
if(instance == null) {
instance = new CounterService();
}
return instance;
}
public StatisticCounter get(String name){
StatisticCounter c = counters.get(name);
if(c == null)throw new IllegalArgumentException("Counter "+name+" not exist");
return c;
}
public void put(String name){
if(name==null)throw new IllegalArgumentException("null can`t be as name");
if(counters.get(name)!=null)throw new IllegalArgumentException("Counter "+name+" exist");
counters.put(name, new Counter(name));
}...
The comments in your question are pointing you in a good direction. Since the answers do not mention it, I'll summarize the general idea in this answer.
Extending WebApplicationException
JAX-RS allows to define direct mapping of Java exceptions to HTTP error responses. By extending WebApplicationException, you can create application specific exceptions that build a HTTP response with the status code and an optional message as the body of the response.
The following exception builds a HTTP response with the 404 status code:
public class CustomerNotFoundException extends WebApplicationException {
/**
* Create a HTTP 404 (Not Found) exception.
*/
public CustomerNotFoundException() {
super(Responses.notFound().build());
}
/**
* Create a HTTP 404 (Not Found) exception.
* #param message the String that is the entity of the 404 response.
*/
public CustomerNotFoundException(String message) {
super(Response.status(Responses.NOT_FOUND).
entity(message).type("text/plain").build());
}
}
WebApplicationException is a RuntimeException and doesn't need to the wrapped in a try-catch block or be declared in a throws clause:
#Path("customers/{customerId}")
public Customer findCustomer(#PathParam("customerId") Long customerId) {
Customer customer = customerService.find(customerId);
if (customer == null) {
throw new CustomerNotFoundException("Customer not found with ID " + customerId);
}
return customer;
}
Creating ExceptionMappers
In other cases it may not be appropriate to throw instances of WebApplicationException, or classes that extend WebApplicationException, and instead it may be preferable to map an existing exception to a response.
For such cases it is possible to use a custom exception mapping provider. The provider must implement the ExceptionMapper<E extends Throwable> interface. For example, the following maps the JAP EntityNotFoundException to a HTTP 404 response:
#Provider
public class EntityNotFoundExceptionMapper
implements ExceptionMapper<EntityNotFoundException> {
#Override
public Response toResponse(EntityNotFoundException ex) {
return Response.status(404).entity(ex.getMessage()).type("text/plain").build();
}
}
When an EntityNotFoundException is thrown, the toResponse(E) method of the EntityNotFoundExceptionMapper instance will be invoked.
The #Provider annotation declares that the class is of interest to the JAX-RS runtime. Such class may be added to the set of classes of the Application instance that is configured.
Introduce a private method such as "apply" which can take function as parameter if you use Java 8. This method will have the error handling and/or mapping, response mapping and response generation code centralized.
From create and delete methods, invoke this apply method and pass the desired counter operation you wish to perform as a lambda expression.
Could you guys please help me find where I made a mistake ?
I switched from SimpleBeanEditorDriver to RequestFactoryEditorDriver and my code no longer saves full graph even though with() method is called. But it correctly loads full graph in the constructor.
Could it be caused by circular reference between OrganizationProxy and PersonProxy ? I don't know what else to think :( It worked with SimpleBeanEditorDriver though.
Below is my client code. Let me know if you want me to add sources of proxies to this question (or you can see them here).
public class NewOrderView extends Composite
{
interface Binder extends UiBinder<Widget, NewOrderView> {}
private static Binder uiBinder = GWT.create(Binder.class);
interface Driver extends RequestFactoryEditorDriver<OrganizationProxy, OrganizationEditor> {}
Driver driver = GWT.create(Driver.class);
#UiField
Button save;
#UiField
OrganizationEditor orgEditor;
AdminRequestFactory requestFactory;
AdminRequestFactory.OrderRequestContext requestContext;
OrganizationProxy organization;
public NewOrderView()
{
initWidget(uiBinder.createAndBindUi(this));
requestFactory = createFactory();
requestContext = requestFactory.contextOrder();
driver.initialize(requestFactory, orgEditor);
String[] paths = driver.getPaths();
createFactory().contextOrder().findOrganizationById(1).with(paths).fire(new Receiver<OrganizationProxy>()
{
#Override
public void onSuccess(OrganizationProxy response)
{
if (response == null)
{
organization = requestContext.create(OrganizationProxy.class);
organization.setContactPerson(requestContext.create(PersonProxy.class));
} else
organization = requestContext.edit(response);
driver.edit(organization, requestContext);
}
#Override
public void onFailure(ServerFailure error)
{
createConfirmationDialogBox(error.getMessage()).center();
}
});
}
private static AdminRequestFactory createFactory()
{
AdminRequestFactory factory = GWT.create(AdminRequestFactory.class);
factory.initialize(new SimpleEventBus());
return factory;
}
#UiHandler("save")
void buttonClick(ClickEvent e)
{
e.stopPropagation();
save.setEnabled(false);
try
{
AdminRequestFactory.OrderRequestContext ctx = (AdminRequestFactory.OrderRequestContext) driver.flush();
if (!driver.hasErrors())
{
// Link to each other
PersonProxy contactPerson = organization.getContactPerson();
contactPerson.setOrganization(organization);
String[] paths = driver.getPaths();
ctx.saveOrganization(organization).with(paths).fire(new Receiver<Void>()
{
#Override
public void onSuccess(Void arg0)
{
createConfirmationDialogBox("Saved!").center();
}
#Override
public void onFailure(ServerFailure error)
{
createConfirmationDialogBox(error.getMessage()).center();
}
});
}
} finally
{
save.setEnabled(true);
}
}
}
with() is only used for retrieval of information, so your with() use with a void return type is useless (but harmless).
Whether a full graph is persisted is entirely up to your server-side code, which is intimately bound to your persistence API (JPA, JDO, etc.)
First, check that the Organization object you receive in your save() method on the server-side is correctly populated. If it's not the case, check your Locators (and/or static findXxx methods) ; otherwise, check your save() method's code.
Judging from the code above, I can't see a reason why it wouldn't work.
It took me some time to realize that the problem was the composite id of Person entity.
Below is the code snippet of PojoLocator that is used by my proxy entities.
public class PojoLocator extends Locator<DatastoreObject, Long>
{
#Override
public DatastoreObject find(Class<? extends DatastoreObject> clazz, Long id)
{
}
#Override
public Long getId(DatastoreObject domainObject)
{
}
}
In order to fetch child entity from DataStore you need to have id of a parent class. In order to achieve that I switched "ID class" for Locator<> to String which represents textual form of Objectify's Key<> class.
Here is how to looks now:
public class PojoLocator extends Locator<DatastoreObject, String>
{
#Override
public DatastoreObject find(Class<? extends DatastoreObject> clazz, String id)
{
Key<DatastoreObject> key = Key.create(id);
return ofy.load(key);
}
#Override
public String getId(DatastoreObject domainObject)
{
if (domainObject.getId() != null)
{
Key<DatastoreObject> key = ofy.fact().getKey(domainObject);
return key.getString();
} else
return null;
}
}
Please note that your implementation may slightly differ because I'm using Objectify4.