Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Tapestry Wiki" for 
change notification.

The following page has been changed by MarceloLotif:
http://wiki.apache.org/tapestry/Tapestry5AnotherSelectWithObjects

The comment on the change is:
Bugs fixed

------------------------------------------------------------------------------
   * 
[http://www.phy6.net/wiki/tiki-index.php?page=Tapestry+5+GenericSelectionModel 
Tapestry5 How to use the SELECT component]
   * ["Tapestry5DisplayableSelectionModel"]
  
- Here, we will create an Annotation, a (not so) new feature from Java 1.5, 
widely know by Tapestry users, to suppress some steps from the other methods, 
like the instantiation of a SelectionModel and a ValueEncoder, or even create 
another component to do the job. Remember, this is an extension, so everything 
we saw in the other components are presented here. What I tried to do is an 
easier way of instantiate the component in the page class.
+ Here, we will create an Annotation, a (not so) new feature from Java 1.5, 
widely known by Tapestry users, to suppress some steps from the other methods, 
like the instantiation of a SelectionModel and a ValueEncoder, or even create 
another component to do the job. Remember, this is an extension, so everything 
we saw in the other components are presented here. What I tried to do is an 
easier way to instantiate the component in the page class.
  
  We will see 4 basic classes here:
   * '''GenericSelectionModel''' - This is the model that the component will 
use to render the options for your Select component.
@@ -30, +30 @@

  import org.apache.tapestry.util.AbstractSelectModel;
  
  public class GenericSelectionModel<T> extends AbstractSelectModel {
-       
+ 
        private PropertyAdapter labelFieldAdapter = null;
+ 
        private List<T> list;
  
        public GenericSelectionModel(List<T> list, String labelField, 
PropertyAccess access) {
                if(labelField != null && !labelField.equalsIgnoreCase("null")){
+                       if(list.size() > 0){
-                       this.labelFieldAdapter = 
access.getAdapter(list.get(0).getClass()).getPropertyAdapter(labelField);
+                               this.labelFieldAdapter = 
access.getAdapter(list.get(0).getClass()).getPropertyAdapter(labelField);
+                       }
                }
                this.list = list;
        }
@@ -49, +52 @@

                List<OptionModel> optionModelList = new 
ArrayList<OptionModel>();
                for (T obj : list) {
                        if (labelFieldAdapter == null) {
-                               optionModelList.add(new 
OptionModelImpl(nvl(obj) + "", false, obj, new String[0]));
+                               optionModelList.add(new 
OptionModelImpl(nvl(obj) + "", false,
+                                               obj, new String[0]));
                        } else {
-                               optionModelList.add(new 
OptionModelImpl(nvl(labelFieldAdapter.get(obj)), false, obj, new String[0]));
+                               optionModelList.add(new 
OptionModelImpl(nvl(labelFieldAdapter
+                                               .get(obj)), false, obj, new 
String[0]));
                        }
                }
                return optionModelList;
        }
-       
+ 
        private String nvl(Object o) {
-         if (o == null)
-             return "";
-         else
-             return o.toString();
-     }
-       
+               if (o == null)
+                       return "";
+               else
+                       return o.toString();
+       }
+ 
  }
  }}}
  
@@ -83, +88 @@

  
        public GenericValueEncoder(List<T> list, String idField, PropertyAccess 
access) {
                if (idField != null && !idField.equalsIgnoreCase("null")){
+                       if(list.size() > 0){
-             this.idFieldAdapter = 
access.getAdapter(list.get(0).getClass()).getPropertyAdapter(idField);
+                               this.idFieldAdapter = 
access.getAdapter(list.get(0).getClass()).getPropertyAdapter(idField);
+                       }
                }
                this.list = list;
        }
@@ -148, +155 @@

  
  So, this way, you don't need to add these lines on every page you create, 
with every Select you make. You just have to decorate the Select's list with 
this annotation and it will insert them for you.
  
- Pot this class on your ''sevices'' package:
+ Put this class on your ''sevices'' package:
  
  {{{
  import java.lang.reflect.Modifier;
  
- import org.apache.tapestry.ioc.internal.services.PropertyAccessImpl;
  import org.apache.tapestry.ioc.internal.util.InternalUtils;
+ import org.apache.tapestry.ioc.services.PropertyAccess;
  import org.apache.tapestry.ioc.util.BodyBuilder;
  import org.apache.tapestry.model.MutableComponentModel;
  import org.apache.tapestry.services.ClassTransformation;
@@ -169, +176 @@

  public class InjectSelectionModelWorker implements 
ComponentClassTransformWorker {
  
      final private Logger _logger = 
LoggerFactory.getLogger(InjectSelectionModelWorker.class);
+     final private PropertyAccess _access;
      
+       public InjectSelectionModelWorker(PropertyAccess propertyAccess) {
+               _access = propertyAccess;
+       }
+ 
        public void transform(ClassTransformation transformation, 
MutableComponentModel componentModel) {
  
                for (String fieldName : 
transformation.findFieldsWithAnnotation(InjectSelectionModel.class)) {
@@ -180, +192 @@

                        }
  
                        String accessActualName = 
transformation.addField(Modifier.PRIVATE, 
"org.apache.tapestry.ioc.services.PropertyAccess", "_access");
-                       transformation.injectField(accessActualName, new 
PropertyAccessImpl());
+                       transformation.injectField(accessActualName, _access);
                        
                        addGetSelectionModelMethod(transformation, fieldName, 
annotation.labelField(), accessActualName);
  
@@ -197, +209 @@

        private void addGetSelectionModelMethod(ClassTransformation 
transformation, String fieldName, String labelField, String accessName) {
                
                String methodName = "get" + 
InternalUtils.capitalize(InternalUtils.stripMemberPrefix(fieldName)) + 
"SelectionModel";
- 
+                               
                String modelQualifiedName = 
(GenericSelectionModel.class).getName();
                TransformMethodSignature sig = 
                        new TransformMethodSignature(Modifier.PUBLIC, 
modelQualifiedName, methodName, null, null);
@@ -241, +253 @@

       * <li>InjectSelectionModel - generates the SelectionModel and 
ValueEncoder for a any marked list of objects.</li>
       * </ul>
       */
-     public static void 
contributeComponentClassTransformWorker(OrderedConfiguration<ComponentClassTransformWorker>
 configuration)
+     public static void 
contributeComponentClassTransformWorker(OrderedConfiguration<ComponentClassTransformWorker>
 configuration, PropertyAccess propertyAccess)
      {
-         configuration.add("InjectSelectionModel", new 
InjectSelectionModelWorker(), "after:Inject*");
+         configuration.add("InjectSelectionModel", new 
InjectSelectionModelWorker(propertyAccess), "after:Inject*");
      }
  }}}
  
  So, let's use it:
- First, declare a list and populate it. Put the annotation on the list and 
pass the '''labelField'' and '''idField'' attributes to it. Then, create the 
item to get the selection. 
+ First, declare a list and populate it. Put the annotation on the list and 
pass the '''labelField''' and '''idField''' attributes to it. Then, create the 
item to get the selection. 
  
  Here's the example:
  {{{
@@ -312, +324 @@

  
  }}}
  
- If you wnat to have a '''List<String>''', just instantiate it and pass 
'''nothing''' as the ''labelField'' and ''idField'' for the annotation.
+ If you want a '''List<String>''', just instantiate it and pass '''nothing''' 
as the ''labelField'' and ''idField'' for the annotation.
  
  '''Important:''' your bean have to override the '''equals()''' method from 
the '''Object''' superclass, so the component can compare your current 
selection with the appropriate bean inside the list. The Eclipse IDE provide a 
simple default implementation that solves the problem. Go to the menu 
'''"Source/Generate hashCode() and equals()..."''' to use this feature.
  

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

Reply via email to