Showing posts with label software development. Show all posts
Showing posts with label software development. Show all posts

Sunday, August 16, 2009

IoC

As I am moving from Java to DotNet, i am re-evaluating IoC containers.

I've been naively using Spring for a while, and unfortunately, missed out on Guice, which, best I can tell is the IoC of my dreams (now lost to me forever, or at least as long as I am on DotNet).

That said, I am growing skeptical of the concept of an IoC container. To take an example from the Guice site. Is this:

public class BillingModule extends AbstractModule {
@Override
protected void configure() {
bind(TransactionLog.class).to(DatabaseTransactionLog.class);
bind(CreditCardProcessor.class).to(PaypalCreditCardProcessor.class);
bind(BillingService.class).to(RealBillingService.class);
}
}
Really so much more awesome than:
  public static void main(String[] args) {
CreditCardProcessor processor = new PaypalCreditCardProcessor();
TransactionLog transactionLog = new DatabaseTransactionLog();
BillingService billingService
= new RealBillingService(creditCardProcessor, transactionLog);
...
}
?

The primary differences -- best I can tell -- are:
  • Without an IoC container, every class ideally announces every dependency via its constructor. This can result in a lot of constructors requiring, e.g.: Loggers, which is, arguably, displeasing aesthetically. This also may not work smoothly with tools that want a no-arg constructor.
  • If your object graph changes, w/o the IoC container, you'd have to change constructors forcing changes to your wiring code before you could compile. With an IoC container, things can, but are not guaranteed, to adapt more magically. You may not be notified that your code is now broken until it fails in run-time.
It is not clear to me that these trade-offs arguing for using an IoC container.

Wednesday, May 6, 2009

Strange YUI Drag Drop onInvalidDrop IE Quirk

I am doing some Javascript drag drop in my application using YUI

I extend DDProxy as in the samples. If the drop is invalid, I want it to revert to the original position. The following works in chrome and firefox but not Internet Explorer 7:


startDrag: function(x, y) {
this.startPos = Dom.getXY(this.getEl());
Dom.setStyle(this.getEl(), "visibility", "hidden");
...

onInvalidDrop: function(e) {
Dom.setStyle(this.getEl(), "visibility", "");
Dom.setXY(this.getEl(), this.startPos);
}


On IE, the DDProxy is left where the drag ends. After some experimentation, I found the following works:


startDrag: function(x, y) {
this.startPos = Dom.getXY(this.getEl());
...

onInvalidDrop: function(e) {
Dom.setStyle(this.getEl(), "visibility", "");
var code = "YAHOO.util.Dom.setXY('" + this.getEl().id + "', [" + this.startPos + "]);";
setTimeout(code,.1);
}


With further trial/error, I settled on the following solution:


startDrag: function(x, y) {
this.startPos = Dom.getXY(this.getEl());
...

endDrag: function(x, y) {
},
onInvalidDrop: function(e) {
Dom.setStyle(this.getEl(), "visibility", "");
Dom.setXY(this.getEl(), this.startPos);
}


Fun!

Monday, December 22, 2008

Grails + JSecurity

I have been using the Grails JSecurity Plugin for authentication/authorization in my proto-type Grails app.

While there are many good things about the JSecurity Grails Plugin, "thorough documentation" is not one of them. I had some difficulty figuring out how to tie it all togethr, so I am posting here my basic set up.

For apps where authorization is, to some degree, external to the core object model, the WildcardPermission is the flexible, powerful way to go.

In my app, however, authorization rules are deeply embedded within the domain model -- whether or not User X can edit object Y is a function of some of Y's member values. I do not see how that can be accomplished via WildcardPermission.

My first cut of a solution involves defining an enum and an interface


public enum PermissionActionEnum {
VIEW, EDIT, EXECUTE, DELETE, CREATE, ...
}

public interface AuthProvider<E> {
public boolean isPermitted(User u, PermissionActionEnum a, E on);
public Class<E> getClazz();
}


Each of these AuthProviders knows how to determine authorization by examining the target object. I have a class "GlobalAuthProvider" which contains references to all the known AuthProviders and its own isPermitted method which delegates appropriately.

I defined a JSecurity Permission to link resource/target with a PermissionAction.


public class ResourcePermission implements org.jsecurity.authz.Permission {
Object resource
PermissionActionEnum action
...
//So that action can be set with either an Enum or String
public void setAction(String name) {
action = PermissionActionEnum.valueOf(name.toUpperCase());
}
}


Next, I defined a groovy authService which wraps the GlobalAuthProvider


public class AuthService {
...
public boolean isPermitted(User user, ResourcePermission resourcePermission) {
GlobalAuthProvider gap = ...
Object on = resourcePermission.resource
PermissionActionEnum action = resourcePermission.action
return gap.isPermitted(user, action, on);
}
...


My Realm then delegates to the authService

class MyRealm {
def authService
...
//Assumes ResourcePermision
def isPermitted(principal, requiredPermission) {
def user = User.findByName( principal )
return authService.isPermitted(user, requiredPermission)
}
...


Now the JSecurity tag can be used in the gsp. This is a little tricky because the GSP jsec:hasPermission tag, appears to be slightly different from the general JSP one


<jsec:hasPermission
permission="${ new ResourcePermission(resource:obj,action:'VIEW') }">
...
</jsec:hasPermission>

JPA + Enum

Frequently in JPA domain models, entities contain "type" objects (for instance: an Employee entity may contain Gender and EmployeeType members).

The simplest Java-centric pattern is to make an Enum of the type object (e.g.: Gender) and mark the member with the @Enumerated annotation.

This is optimal so long as the list of types is more or less static (as in the Employee.Gender). If the list is more dynamic (as in, perhaps, in the Employee.EmployeeType) and especially if the list must be user modifiable, the entity member can obviously not be an Enum.

On the other hand, the general benefits -- stricter type checking, handy case statement, etc -- of Enum-inity still hold.

For this purpose, I have been using a hybrid pattern. Basically, my type entities have a referance to an enum and the enum refers back to the entity. Both have an identifying Name property. There is a special Enum.NA for those Entities not reflected in the Enum.

The way this works is I define interfaces like:


public interface LookupType extends Serializable {
public String getName();
public void setName(String s);
}

public interface LookupTypeEntity<E extends Enum> extends LookupType {
public E getEnum();
}
public interface LookupTypeEnum<E extends LookupTypeEntity<?>> extends LookupType {
public E getEntity();
}


So for example an EmployeeType might look like


@Entity
...
public class EmployeeType implements LookupTypeEntity<EmployeeTypeEnum> {
...
public EmployeeTypeEnum getEnum() {
return LookupTypeHelper.getEnum(this, EmployeeTypeEnum.class);
}
}

public enum EmployeeTypeEnum implements LookupTypeEnum<EmployeeType> {
KING, LORD, SERF, NA
;
private EmployeeType _entity;
private synchronized void initEntity() {
if (_entity == null) {
_entity = LookupTypeHelper.getEntity(this, EmployeeType.class);
}
}
public String getName() {
return name();
}
public void setName(String s) {
throw new UnsupportedOperationException();
}
public EmployeeType getEntity() {
if (_entity == null) {
initEntity();
}
return _entity;
}
}


In the helper class, I provide methods for traversing between the entity and the enum.


public static <T extends LookupTypeEntity<?>> T getEntity(LookupTypeEnum<T> e, Class<T> clazz) {
T t = null;
if ( ! NA.equals(e.getName() )) {
//Dao is a simple class I wrote that wraps a JPA Entity Manager
Dao<T> dao = ...
boolean entityExists = false;
try {
t = dao.findByName(e.getName());
entityExists = t != null;
} catch (NoResultException x) {
}
if (! entityExists ) {
logger.log(Level.INFO, clazz.getSimpleName() + " \'" + e.getName() + "\' not found in database. Creating...");
try {
t = clazz.newInstance();
t.setName( e.getName() );
t = dao.create(t);
logger.log(Level.INFO, "Created: " + t);
} catch (Exception ignore) {
logger.log(Level.WARNING,"Trying to instantiate " + clazz, ignore);
}
}
}
return t;

}

public static <E extends Enum<E>> E getEnum(LookupTypeEntity<E> t, Class<E> clazz) {
E e = Enum.valueOf(clazz, t.getName());
if (e == null) {
e = Enum.valueOf(clazz, NA);
}
return e;
}

Monday, December 8, 2008

Grails GUI

For my nascent grails app I am using YUI + Grails GUI.

Ran into the problem described here, where one autocomplete options containers renders under another autocomplete text input.

The best fix I (described in jira) found was adding a zIndex property to the gui:autoComplete tag and setting the parent container div with it.

Monday, December 1, 2008

Grails Many To Many

Grails doesn't yet handle many-to-many relationships in the scaffolding.

Most of the stuff available online recommends using relationship domain class to fudge the many-to-many relationship. If I have a many to many relationship of User to Role, I could have a UserRoleRelation that has a one-to-many relationship with both a User and Role, which Grails should handle cleanly.

It is also pretty easy to set up a simple direct ManyToMany relationship manually, as follows:

In my Role.java class I have

@ManyToMany(targetEntity=User.class, mappedBy="roleCollection")
private Set userCollection;

In my User.java class I have

@ManyToMany(targetEntity=Role.class, cascade = {CascadeType.MERGE})
@JoinTable(name="USER_ROLE_XREF",
joinColumns=@JoinColumn(name="User_Name", referencedColumnName = "User_Name"),
inverseJoinColumns=@JoinColumn(name="Role_Name", referencedColumnName = "Role_Name")
)
private Set roleCollection;

I cross-refrence by name instead of id to make the table more human readable. This may have the unfortunate side effect of breaking the generate-views command.

In the user/edit.gsp, I add a select box with the list of roles available

<tr class="prop">
<td valign="top" class="name">
<label for="roleCollection">Roles:
</td>
<td valign="top" class="value ${hasErrors(bean:user,field:'roleCollection','errors')}">
<g:select name="newRoleCollection" from="${Role.list()}"
value="${user?.roleCollection?.id}" optionKey="id" multiple="multiple" />
</td>
</tr>

If you only want to present a subset of the Roles (which happens to be the case in my prototype app), you can use Role.findAllByXXX instead of Role.list()

Finally, in my controllers/UserController.groovy, I add the code to put humpty dumpty back together again.

user.roleCollection.clear()

//probably a groovier way to do this, but it works...
//if newRoleCollection is a string instead of a string[], each iterates over each character
boolean newRoleCollectionIsStringArray = params.newRoleCollection.class.name != 'java.lang.String'

if (newRoleCollectionIsStringArray) {
params.newRoleCollection.each{
user.roleCollection.add( Role.findById( Integer.valueOf( it ) ) )
}
} else {
user.roleCollection.add( Role.findById( Integer.valueOf( params.newRoleCollection ) ) )
}

It isn't pretty but it does the trick.

Grails

Been playing with Grails (http://grails.org/).

Positive first impressions: Conceptually, what is not to like about the possibility of defining your domain model and having a functioning GUI up in a few clicks? The Grails generated web-app code and structure appears much neater then, for example, what JBoss SEAM produced. I am also, for the moment, loving writing web-app controllers in Groovy. It feels so much more natural, for that purpose, then Java.

On the negative side: Conceptually, I don't see any non-trivial benefit to defining domain classes in Groovy instead of Java. On the contrary, it seems to me, that in any real enterprise context, you are going to want to define your domain (and perhaps a service layer) in Java. Additionally, if you use Java domain objects, you can reverse engineer them from the database using a tool like hbm2ddl. The development focus on POGOs makes me a little nervous that maybe the Grails development team is more focused on replicating Rails then really thinking about how Grails can most naturally fit into an Enterprise Java environment. The purchase by SpringSource does offset this fear.


Finally, grails seems to enjoy failing without useful error messages. For example: I ran into http://jira.codehaus.org/browse/GRAILS-2096 and http://jira.codehaus.org/browse/GRAILS-3658