001: /*
002: * $Id: Bean.java 497654 2007-01-19 00:21:57Z rgielen $
003: *
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021: package org.apache.struts2.components;
022:
023: import java.io.Writer;
024:
025: import org.apache.commons.logging.Log;
026: import org.apache.commons.logging.LogFactory;
027: import org.apache.struts2.views.annotations.StrutsTag;
028: import org.apache.struts2.views.annotations.StrutsTagAttribute;
029:
030: import com.opensymphony.xwork2.inject.Inject;
031: import com.opensymphony.xwork2.util.ClassLoaderUtil;
032: import com.opensymphony.xwork2.ObjectFactory;
033: import com.opensymphony.xwork2.util.OgnlUtil;
034: import com.opensymphony.xwork2.util.ValueStack;
035:
036: /**
037: * <!-- START SNIPPET: javadoc -->
038: * <p>Instantiates a class that conforms to the JavaBeans specification. This tag has a body which can contain
039: * a number of {@link Param} elements to set any mutator methods on that class.</p>
040: * <p/>
041: * <p>If the id attribute is set on the BeanTag, it will place the instantiated bean into the
042: * stack's Context.</p>
043: * <p/>
044: * <!-- END SNIPPET: javadoc -->
045: *
046: *
047: * <!-- START SNIPPET: params -->
048: * <ul>
049: * <li>id - the stack's context id (if supplied) that the created bean will be store under</li>
050: * <li>name* - the class name of the bean to be instantiated (must respect JavaBean specification)</li>
051: * </ul>
052: * <!-- END SNIPPET: params -->
053: *
054: *
055: * <p>Examples:</p>
056: * <p/>
057: * <pre>
058: * <!-- START SNIPPET: examples -->
059: * <-- in freemarker form -->
060: * [@s.bean name="org.apache.struts2.example.counter.SimpleCounter" id="counter"]
061: * [s:param name="foo" value="BAR"/]
062: * The value of foo is : [s:property value="foo"/], when inside the bean tag.<br />
063: * [/s:bean]
064: *
065: * <-- in jsp form -->
066: * <s:bean name="org.apache.struts2.example.counter.SimpleCounter" id="counter">
067: * <s:param name="foo" value="BAR" />
068: * The value of foot is : <s:property value="foo"/>, when inside the bean tag <br />
069: * </s:bean>
070: * <!-- END SNIPPET: examples -->
071: * </pre>
072: * <p/>
073: *
074: * <!-- START SNIPPET: examplesdescription -->
075: * <p>This example instantiates a bean called SimpleCounter and sets the foo property (setFoo('BAR')). The
076: * SimpleCounter object is then pushed onto the Valuestack, which means that we can call its accessor methods (getFoo())
077: * with the Property tag and get their values.</p>
078: * <p/>
079: * <p>In the above example, the id has been set to a value of <i>counter</i>. This means that the SimpleCounter class
080: * will be placed into the stack's context. You can access the SimpleCounter class using a Struts tag:</p>
081: * <p/>
082: * <pre>
083: * <-- jsp form -->
084: * <s:property value="#counter" />
085: *
086: * <-- freemarker form -->
087: * [s:property value="#counter.foo"/]
088: * </pre>
089: * <p/>
090: * <p>In the property tag example, the <i>#</i> tells Ognl to search the context for the SimpleCounter class which has
091: * an id(key) of <i>counter</i></p>
092: * <!-- END SNIPPET: examplesdescription -->
093: *
094: * @see Param
095: */
096: @StrutsTag(name="bean",tldTagClass="org.apache.struts2.views.jsp.BeanTag",description="Instantiate a JavaBean and place it in the context")
097: public class Bean extends Component {
098: protected static Log log = LogFactory.getLog(Bean.class);
099:
100: protected Object bean;
101: protected String name;
102: protected ObjectFactory objectFactory;
103:
104: public Bean(ValueStack stack) {
105: super (stack);
106: }
107:
108: @Inject
109: public void setObjectFactory(ObjectFactory objectFactory) {
110: this .objectFactory = objectFactory;
111: }
112:
113: public boolean start(Writer writer) {
114: boolean result = super .start(writer);
115:
116: ValueStack stack = getStack();
117:
118: try {
119: String beanName = findString(name, "name",
120: "Bean name is required. Example: com.acme.FooBean");
121: bean = objectFactory.buildBean(ClassLoaderUtil.loadClass(
122: beanName, getClass()), stack.getContext());
123: } catch (Exception e) {
124: log.error("Could not instantiate bean", e);
125:
126: return false;
127: }
128:
129: // push bean on stack
130: stack.push(bean);
131:
132: // store for reference later
133: if (getId() != null) {
134: getStack().getContext().put(getId(), bean);
135: }
136:
137: return result;
138: }
139:
140: public boolean end(Writer writer, String body) {
141: ValueStack stack = getStack();
142: stack.pop();
143:
144: return super .end(writer, body);
145: }
146:
147: public void addParameter(String key, Object value) {
148: OgnlUtil.setProperty(key, value, bean, getStack().getContext());
149: }
150:
151: @StrutsTagAttribute(description="The class name of the bean to be instantiated (must respect JavaBean specification)",required=true)
152: public void setName(String name) {
153: this.name = name;
154: }
155: }
|