donderdag 20 maart 2014

ADF - Throwing a validation exception from a view row object

In ADF, you can easily add method validators on Entity level. However, sometimes this is not enough. If your validation logic is complex (for instance: if you need all other rows to validate against, for some kind of special uniqueness constraint), this is not enough.

You can throw a general exception from the setter of your attribute in the view object, but that is not enough, because this will look different (no 'red' field, and a different style of exception on the screen).

To solve this, you will need to throw an 'AttrValException', as shown below:

General method in the view row base class.

Final static String RESOURCE_BUNDLE_NAME = "my_resource_bundle";
   
protected void throwValidationException(String message, String attrName) {
    PropertiesBundleDef resBundle = new PropertiesBundleDef(this.getViewDef());
    resBundle.setPropertiesFile(RESOURCEBUNDLE_NAME);
    throw new AttrValException(MetaObjectBase.TYP_VIEW_OBJECT, resBundle, message, getViewObject().getFullName(), attrName);
}

Setter of view row object:

public void setMyCode(String value){
    if(/* your validation logic */){
       throwValidationException("myCodeValidationErrorMsgKey", "MyCode");
    }
    setAttributeInternal(MY_CODE, value);
} 


donderdag 3 januari 2013

ikwileenspel.be

De beste gezelschapsspellen voor de beste prijs: www.ikwileenspel.be

Vanaf nu verkopen we dus bord- en kaartspellen. Neem maar eens een kijkje op onze website :-)

maandag 27 juni 2011

Eclipse startup - eclipse.core.internal.dtree.ObjectNotFoundException

After killing the eclipse process and restarting my pc, Eclipse was not able to startup anymore.

In my log file (workspace_dir\.metadata\.log), I saw following exception:

  org.eclipse.core.internal.dtree.ObjectNotFoundException: Tree element 'mypckg/myClass.class' not found.
    at org.eclipse.core.internal.dtree.AbstractDataTree.handleNotFound(AbstractDataTree.java:257)
    at org.eclipse.core.internal.dtree.DeltaDataTree.getData(DeltaDataTree.java:585)
    at org.eclipse.core.internal.dtree.DataDeltaNode.asBackwardDelta(DataDeltaNode.java:50)
    at org.eclipse.core.internal.dtree.DataDeltaNode.asBackwardDelta(DataDeltaNode.java:47)
    at org.eclipse.core.internal.dtree.DataDeltaNode.asBackwardDelta(DataDeltaNode.java:47)
    at org.eclipse.core.internal.dtree.DataDeltaNode.asBackwardDelta(DataDeltaNode.java:47)
    at org.eclipse.core.internal.dtree.DataDeltaNode.asBackwardDelta(DataDeltaNode.java:47)

After some research I tried to delete the workspace_dir\.metadata\.plugins\org.eclipse.core.resources\.snap file, which solved the problem. Don't ask me why. You can tell me why if you know :-)

maandag 9 mei 2011

PrimeFaces inplace wrapped around editor

In Primefaces, there is a <p:inplace> component, which is a nice component to use for inline editing,
and a <p:editor>, which is an input component with rich text formatting capabilities.


But the two didn't really match. If one uses a <p:inplace> wrapped around a <p:editor>, the editor does not work as it is supposed to. The problem is that the editor is not designed to work in a container which is initially hidden. And that's just the behavior you depend on when you want to use an inplace component.


However, with this little trick, you can use an inplace component wrapped around an editor. The editor has a 'lazy' property. If you set this to true, you can initialize the editor at the moment it is shown:

  <h:form id="formWithInplace">
    <p:inplace id="inplaceid">
      <p:editor value="#{editorBean.value}" saveListener="#{editorBean.save}"
                                lazy="true" widgetVar="editorWidget"/>
    </p:inplace>

  </h:form>

So now we have an inplace wrapped around a lazy editor. The only thing we have to do now, is initialize the editor when the inplace is clicked (and the editor is shown). As the inplace does not have an 'onclick' parameter, we will use jQuery and the id of the inplace component:


  <script type="text/javascript">
    jQuery(PrimeFaces.escapeClientId('formWithInplace:inplaceid')).click(
      function(){
        editorWidget.init();
      }
    );
  </script>


vrijdag 15 april 2011

Seam 3 / Weld alternative for @Startup annotation

In Seam 2, if you wanted a seam component to be initialized when the application was started up, you could use the @Startup annotation.

In Seam 3 (or better: weld), this annotation is not supported. If you want a bean to be started up when the application starts up, you could write a method which observes an event:

  public class BeanToBeInitializedAtStartup {
public void onStartup(@Observes @Initialized WebApplication webApplication){
//do nothing, bean will be initialized when application is started
    }

  }

However, this means you will need such a method for every bean, which is a lot more of overhead than the simple @Startup annotation.

A solution for this is to use a simple helper class, which initializes all beans which implement some interface you define yourself:

First, you will need an interface. This interface does not require any methods.

  public interface Startup { }


Next, all of the beans you want to be initialized should implement this interface

  public class BeanToBeInitializedAtStartup implements Startup { }
That looks a lot better! Now of course you need some helper class, which initializes all beans which implement the Startup annotation:

  public class BeanStartupHelper {


    public void onStartup(@Observes @Initialized WebApplication webApplication, 
                          BeanManager beanManager) {
      
      for(Bean bean : beanManager.getBeans(Startup.class)){
       CreationalContext context = beanManager.createCreationalContext(bean);
       beanManager.getReference(bean, Startup.class, context);
     }
 
    }
  }

The BeanStartupHelper is actually also a bean, and as you can see, this bean contains a method which observes the initialization of the webapplication. A reference to the BeanManager object is injected as a parameter of this method. We use the BeanManager object to create the beans we need, which are all beans which implement the Startup annotation.

Result
There is a clear separation between the beans themselves and the implementation of the startup method. The only thing needed for your beans is the fact that they need to implement a Startup interface. You only need one method which observes the initialization of your application, in which all 'startup' beans will be initialized!