View Javadoc

    1   /*
    2    * $Id: Bean.java 497654 2007-01-19 00:21:57Z rgielen $
    3    *
    4    * Licensed to the Apache Software Foundation (ASF) under one
    5    * or more contributor license agreements.  See the NOTICE file
    6    * distributed with this work for additional information
    7    * regarding copyright ownership.  The ASF licenses this file
    8    * to you under the Apache License, Version 2.0 (the
    9    * "License"); you may not use this file except in compliance
    10   * with the License.  You may obtain a copy of the License at
    11   *
    12   *  http://www.apache.org/licenses/LICENSE-2.0
    13   *
    14   * Unless required by applicable law or agreed to in writing,
    15   * software distributed under the License is distributed on an
    16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    17   * KIND, either express or implied.  See the License for the
    18   * specific language governing permissions and limitations
    19   * under the License.
    20   */
    21  package org.apache.struts2.components;
    22
    23  import java.io.Writer;
    24
    25  import org.apache.commons.logging.Log;
    26  import org.apache.commons.logging.LogFactory;
    27  import org.apache.struts2.views.annotations.StrutsTag;
    28  import org.apache.struts2.views.annotations.StrutsTagAttribute;
    29
    30  import com.opensymphony.xwork2.inject.Inject;
    31  import com.opensymphony.xwork2.util.ClassLoaderUtil;
    32  import com.opensymphony.xwork2.ObjectFactory;
    33  import com.opensymphony.xwork2.util.OgnlUtil;
    34  import com.opensymphony.xwork2.util.ValueStack;
    35
    36  /***
    37   * <!-- START SNIPPET: javadoc -->
    38   * <p>Instantiates a class that conforms to the JavaBeans specification. This tag has a body which can contain
    39   * a number of {@link Param} elements to set any mutator methods on that class.</p>
    40   * <p/>
    41   * <p>If the id attribute is set on the BeanTag, it will place the instantiated bean into the
    42   * stack's Context.</p>
    43   * <p/>
    44   * <!-- END SNIPPET: javadoc -->
    45   *
    46   *
    47   * <!-- START SNIPPET: params -->
    48   * <ul>
    49   *      <li>id - the stack's context id (if supplied) that the created bean will be store under</li>
    50   *      <li>name* - the class name of the bean to be instantiated (must respect JavaBean specification)</li>
    51   * </ul>
    52   * <!-- END SNIPPET: params -->
    53   *
    54   *
    55   * <p>Examples:</p>
    56   * <p/>
    57   * <pre>
    58   * <!-- START SNIPPET: examples -->
    59   * &lt;-- in freemarker form --&gt;
    60   * [@s.bean name="org.apache.struts2.example.counter.SimpleCounter" id="counter"]
    61   *   [s:param name="foo" value="BAR"/]
    62   *   The value of foo is : [s:property value="foo"/], when inside the bean tag.<br />
    63   * [/s:bean]
    64   *
    65   * &lt;-- in jsp form --&gt;
    66   * &lt;s:bean name="org.apache.struts2.example.counter.SimpleCounter" id="counter"&gt;
    67   *   &lt;s:param name="foo" value="BAR" /&gt;
    68   *   The value of foot is : &lt;s:property value="foo"/&gt;, when inside the bean tag &lt;br /&gt;
    69   * &lt;/s:bean&gt;
    70   * <!-- END SNIPPET: examples -->
    71   * </pre>
    72   * <p/>
    73   *
    74   * <!-- START SNIPPET: examplesdescription -->
    75   * <p>This example instantiates a bean called SimpleCounter and sets the foo property (setFoo('BAR')). The
    76   * SimpleCounter object is then pushed onto the Valuestack, which means that we can call its accessor methods (getFoo())
    77   * with the Property tag and get their values.</p>
    78   * <p/>
    79   * <p>In the above example, the id has been set to a value of <i>counter</i>. This means that the SimpleCounter class
    80   * will be placed into the stack's context. You can access the SimpleCounter class using a Struts tag:</p>
    81   * <p/>
    82   * <pre>
    83   * &lt;-- jsp form --&gt;
    84   * &lt;s:property value="#counter" /&gt;
    85   *
    86   * &lt;-- freemarker form --&gt;
    87   * [s:property value="#counter.foo"/]
    88   * </pre>
    89   * <p/>
    90   * <p>In the property tag example, the <i>#</i> tells Ognl to search the context for the SimpleCounter class which has
    91   * an id(key) of <i>counter</i></p>
    92   * <!-- END SNIPPET: examplesdescription -->
    93   *
    94   * @see Param
    95   */
    96  @StrutsTag(name="bean", tldTagClass="org.apache.struts2.views.jsp.BeanTag",
    97          description="Instantiate a JavaBean and place it in the context")
    98  public class Bean extends Component {
    99      protected static Log log = LogFactory.getLog(Bean.class);
    100
    101     protected Object bean;
    102     protected String name;
    103     protected ObjectFactory objectFactory;
    104
    105     public Bean(ValueStack stack) {
    106         super(stack);
    107     }
    108
    109     @Inject
    110     public void setObjectFactory(ObjectFactory objectFactory) {
    111         this.objectFactory = objectFactory;
    112     }
    113
    114     public boolean start(Writer writer) {
    115         boolean result = super.start(writer);
    116
    117         ValueStack stack = getStack();
    118
    119         try {
    120             String beanName = findString(name, "name", "Bean name is required. Example: com.acme.FooBean");
    121             bean = objectFactory.buildBean(ClassLoaderUtil.loadClass(beanName, getClass()), stack.getContext());
    122         } catch (Exception e) {
    123             log.error("Could not instantiate bean", e);
    124
    125             return false;
    126         }
    127
    128         // push bean on stack
    129         stack.push(bean);
    130
    131         // store for reference later
    132         if (getId() != null) {
    133             getStack().getContext().put(getId(), bean);
    134         }
    135
    136         return result;
    137     }
    138
    139     public boolean end(Writer writer, String body) {
    140         ValueStack stack = getStack();
    141         stack.pop();
    142
    143         return super.end(writer, body);
    144     }
    145
    146     public void addParameter(String key, Object value) {
    147         OgnlUtil.setProperty(key, value, bean, getStack().getContext());
    148     }
    149
    150     @StrutsTagAttribute(description="The class name of the bean to be instantiated (must respect JavaBean specification)",
    151                         required=true)
    152     public void setName(String name) {
    153         this.name = name;
    154     }
    155 }