I've implemented a little solution to inject SpringBean of Wicket Pages on
the un-serialization event :

1 - Make the SpringContext available in a static way :

public class MyWebApplication extends SpringWebApplication {

    private static ApplicationContext springApplicationContext = null ;
   
        @Override
          protected void init() {
                  super.init();
                  addComponentInstantiationListener(new 
SpringComponentInjector(this));
                
                  springApplicationContext = 
getSpringContextLocator().getSpringContext()
;
                
     (...)


        public static ApplicationContext getApplicationContext(){
                  return springApplicationContext ;
          }

     (...)
}


2 - Define an Helper to inspect by introspection your classes in order to : 
   select all transiant fields having a SpringBean and a Required annotation 
   make access to the setter method of the fields (throw all super classes
of it)


public class AnnotatedFieldHelper{

        private Class clazz ;
        
        private Field field = null;

        private boolean isTransient = false;

        private boolean isSpringBean = false;

        private boolean isRequired = false;

        private String springBeanName = null;
        

    (...)
   
        /**
         * Build a list of all transient field of the Class
         * @param clazz
         * @return
         */
        public static List<AnnotatedField> getTransientAnnotatedField(Class 
clazz)
{

                List<AnnotatedField> list = new ArrayList<AnnotatedField>();

               List<Field> fields = new ArrayList<Field>() ;
        
                // Get all fields (event field from the super classes )
                Class cl = clazz ;
                do{
                        for (Field f : cl.getDeclaredFields()){
                                fields.add(f) ;
                        }
                        cl = cl.getSuperclass() ;
                }while ( cl != null   ) ;
                                
                
                for (Field f : fields) {
                        if (Modifier.isTransient(f.getModifiers())) {

                                AnnotatedField af = new AnnotatedField(clazz, 
f);
                                af.setTransient(true);

                                Annotation[] annotations = f.getAnnotations();
                                for (Annotation a : annotations) {
                                        if (a instanceof SpringBean) {
                                                af.setSpringBean(true);

                                                SpringBean sb = (SpringBean) a;
                                                String patternStr =
"@org.apache.wicket.spring.injection.annot.SpringBean\\(name=(.*)\\)";
                                                Pattern pattern = 
Pattern.compile(patternStr);
                                                Matcher matcher = 
pattern.matcher("");
                                                matcher.reset(sb.toString());
                                                if (matcher.find()) {
                                                        
af.setSpringBeanName(matcher.group(1));
                                                }else{
                                                        
af.setSpringBeanName(null);
                                                }
                                        }
                                }

                                String setterName = getSetterName (f.getName());
                                boolean isRequired = false;
                                try {
                                        Method setter = 
clazz.getMethod(setterName, f.getType());
                                        Annotation[] annotationsSetter = 
setter.getAnnotations();
                                        for (Annotation a : annotationsSetter) {
                                                if (a instanceof Required) {
                                                        isRequired = true;
                                                }
                                        }
                                } catch (NoSuchMethodException e) {
                                        isRequired = false;
                                } catch (SecurityException e) {
                                        isRequired = false;
                                }

                                af.setRequired(isRequired);
                                list.add(af);
                        }
                }
                return list;
        }


} 


3 - Define a super class for all your Wicket Page to serialize all transiant
SpringBean

public class MySuperPage extends WebPage {


        @Override
        public ApplicationContext getApplicationContext(){
                return MyWebApplication.getApplicationContext() ;
        }


        /**
         * Set all transient fields of the page managed by Spring from the 
spring
         * context
         * 
         * @throws RuntimeException
         */
        protected void setAllTransientSpringFields() throws RuntimeException {

                List<AnnotatedField> tafList =
AnnotatedFieldHelper.getTransientAnnotatedField(getClass());
                for (AnnotatedField af : tafList) {
                        if (af.isSpringBean() && af.getSpringBeanName() != 
null) {
                                try {
                                        Object bean = 
getApplicationContext().getBean(af.getSpringBeanName());
                                        af.getSetter().invoke(this, bean);
                                } catch (BeansException e) {
                                        throw new RuntimeException("Impossible 
to get " +
af.getSpringBeanName()
                                                        + " the from the Spring 
Context");
                                } catch (Exception e) {
                                        throw new RuntimeException("Impossible 
to set " +
af.getField().getName());
                                }
                        }
                }
        }


4 - Put transiant all SpringBean not serializable of the Wicket Page and
define the readObject method using your helper 

public class MyPage extends MySuperPage {

  private static final long serialVersionUID = 1L;

        @SpringBean(name = "mySpringBean")
        transient MyPOJO config;

        @Required
        public void setMyPOJO(MyPOJO config) {
                this.config = config;
        }

  (...)


        /**
         * Creates transient objects
         * Annotation introspection for all Required transient field
         */
        private void readObject(ObjectInputStream stream) throws IOException,
ClassNotFoundException {
                stream.defaultReadObject();
                setAllTransientSpringFields();
        }



-----------------------------------------------------------------------------

Some questions ?
  - Is it a good way do that ?
  - Is there an existing helper to do that ?
  - If it's a good way and if ther is no existing helper, can i contrib to
Wicket ?
  
Regards,


Gerald Reinhart

-- 
View this message in context: 
http://www.nabble.com/%40SpringBean-and-serialization-tp15330505p18691954.html
Sent from the Wicket - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to