Coverage report

| %line | %branch
--- | --- | ---

org.apache.commons.jelly.impl.DynamicBeanTag

0%

0%

1

     /*

2

      * Copyright 2002,2004 The Apache Software Foundation.

3

      *

4

      * Licensed under the Apache License, Version 2.0 (the "License");

5

      * you may not use this file except in compliance with the License.

6

      * You may obtain a copy of the License at

7

      *

8

      *      http://www.apache.org/licenses/LICENSE-2.0

9

      *

10

      * Unless required by applicable law or agreed to in writing, software

11

      * distributed under the License is distributed on an "AS IS" BASIS,

12

      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

13

      * See the License for the specific language governing permissions and

14

      * limitations under the License.

15

      */

16

     package org.apache.commons.jelly.impl;

17

18

     import java.lang.reflect.InvocationTargetException;

19

     import java.lang.reflect.Method;

20

     import java.util.HashSet;

21

     import java.util.Iterator;

22

     import java.util.Map;

23

     import java.util.Set;

24

25

     import org.apache.commons.beanutils.ConvertingWrapDynaBean;

26

     import org.apache.commons.collections.BeanMap;

27

     import org.apache.commons.jelly.DynaBeanTagSupport;

28

     import org.apache.commons.jelly.JellyTagException;

29

     import org.apache.commons.jelly.MissingAttributeException;

30

     import org.apache.commons.jelly.Tag;

31

     import org.apache.commons.jelly.XMLOutput;

32

     import org.apache.commons.jelly.expression.Expression;

33

     import org.apache.commons.logging.Log;

34

     import org.apache.commons.logging.LogFactory;

35

36

     /**

37

      * This tag is bound onto a Java Bean class. When the tag is invoked a bean will be created

38

      * using the tags attributes.

39

      * The bean may also have an invoke method called invoke(), run(), execute() or some such method

40

      * which will be invoked after the bean has been configured.</p>

41

      *

42

      * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>

43

      * @author <a href="mailto:jason@zenplex.com">Jason van Zyl</a>

44

      * @version $Revision: 155420 $

45

      */

46

     public class DynamicBeanTag extends DynaBeanTagSupport implements BeanSource {

47

48

         /** The Log to which logging calls will be made. */

49

0

         private static final Log log = LogFactory.getLog(DynamicBeanTag.class);

50

51

         /** Empty arguments for Method.invoke() */

52

0

         private static final Object[] emptyArgs = {};

53

54

         /** the bean class */

55

         private Class beanClass;

56

57

         /** the current bean instance */

58

         private Object bean;

59

60

         /** the method to invoke on the bean */

61

         private Method method;

62

63

         /**

64

          * the tag attribute name that is used to declare the name

65

          * of the variable to export after running this tag

66

          */

67

         private String variableNameAttribute;

68

69

         /** the current variable name that the bean should be exported as */

70

         private String var;

71

72

         /** the set of attribute names we've already set */

73

0

         private Set setAttributesSet = new HashSet();

74

75

         /** the attribute definitions */

76

         private Map attributes;

77

78

         /**

79

          *

80

          * @param beanClass Class of the bean that will receive the setter events

81

          * @param attributes

82

          * @param variableNameAttribute

83

          * @param method method of the Bean to invoke after the attributes have been set.  Can be null.

84

          */

85

0

         public DynamicBeanTag(Class beanClass, Map attributes, String variableNameAttribute, Method method) {

86

0

             this.beanClass = beanClass;

87

0

             this.method = method;

88

0

             this.attributes = attributes;

89

0

             this.variableNameAttribute = variableNameAttribute;

90

0

         }

91

92

         public void beforeSetAttributes() throws JellyTagException {

93

             // create a new dynabean before the attributes are set

94

             try {

95

0

                 bean = beanClass.newInstance();

96

0

                 setDynaBean( new ConvertingWrapDynaBean( bean ) );

97

0

             } catch (InstantiationException e) {

98

0

                 throw new JellyTagException("Could not instantiate dynabean",e);

99

0

             } catch (IllegalAccessException e) {

100

0

                 throw new JellyTagException("Could not instantiate dynabean",e);

101

0

             }

102

103

0

             setAttributesSet.clear();

104

0

         }

105

106

         public void setAttribute(String name, Object value) throws JellyTagException {

107

0

             boolean isVariableName = false;

108

0

             if (variableNameAttribute != null ) {

109

0

                 if ( variableNameAttribute.equals( name ) ) {

110

0

                     if (value == null) {

111

0

                         var = null;

112

0

                     }

113

                     else {

114

0

                         var = value.toString();

115

                     }

116

0

                     isVariableName = true;

117

                 }

118

             }

119

0

             if (! isVariableName) {

120

121

                 // #### strictly speaking we could

122

                 // know what attributes are specified at compile time

123

                 // so this dynamic set is unnecessary

124

0

                 setAttributesSet.add(name);

125

126

                 // we could maybe implement attribute specific validation here

127

128

0

                 super.setAttribute(name, value);

129

             }

130

0

         }

131

132

         // Tag interface

133

         //-------------------------------------------------------------------------

134

         public void doTag(XMLOutput output) throws JellyTagException {

135

136

             // lets find any attributes that are not set and

137

0

             for ( Iterator iter = attributes.values().iterator(); iter.hasNext(); ) {

138

0

                 Attribute attribute = (Attribute) iter.next();

139

0

                 String name = attribute.getName();

140

0

                 if ( ! setAttributesSet.contains( name ) ) {

141

0

                     if ( attribute.isRequired() ) {

142

0

                         throw new MissingAttributeException(name);

143

                     }

144

                     // lets get the default value

145

0

                     Object value = null;

146

0

                     Expression expression = attribute.getDefaultValue();

147

0

                     if ( expression != null ) {

148

0

                         value = expression.evaluate(context);

149

                     }

150

151

                     // only set non-null values?

152

0

                     if ( value != null ) {

153

0

                         super.setAttribute(name, value);

154

                     }

155

                 }

156

0

             }

157

158

             // If the dynamic bean is itself a tag, let it execute itself

159

0

             if (bean instanceof Tag)

160

             {

161

0

                 Tag tag = (Tag) bean;

162

0

                 tag.setBody(getBody());

163

0

                 tag.setContext(getContext());

164

0

                 tag.setParent(getParent());

165

0

                 ((Tag) bean).doTag(output);

166

167

0

                 return;

168

             }

169

170

0

             invokeBody(output);

171

172

             // export the bean if required

173

0

             if ( var != null ) {

174

0

                 context.setVariable(var, bean);

175

             }

176

177

             // now, I may invoke the 'execute' method if I have one

178

0

             if ( method != null ) {

179

                 try {

180

0

                     method.invoke( bean, emptyArgs );

181

                 }

182

0

                 catch (IllegalAccessException e) {

183

0

                     methodInvocationException(bean, method, e);

184

                 }

185

0

                 catch (IllegalArgumentException e) {

186

0

                     methodInvocationException(bean, method, e);

187

                 }

188

0

                 catch (InvocationTargetException e) {

189

                     // methodInvocationError(bean, method, e);

190

191

0

                     Throwable inner = e.getTargetException();

192

193

0

                     throw new JellyTagException(inner);

194

195

0

                 }

196

             }

197

0

         }

198

199

         /**

200

          * Report the state of the bean when method invocation fails

201

          * so that the user can determine any problems that might

202

          * be occuring while using dynamic jelly beans.

203

          *

204

          * @param bean Bean on which <code>method</code was invoked

205

          * @param method Method that was invoked

206

          * @param e Exception throw when <code>method</code> was invoked

207

          */

208

         private void methodInvocationException(Object bean, Method method, Exception e) throws JellyTagException {

209

0

             log.error("Could not invoke " + method, e);

210

0

             BeanMap beanMap = new BeanMap(bean);

211

212

0

             log.error("Bean properties:");

213

0

             for (Iterator i = beanMap.keySet().iterator(); i.hasNext();) {

214

0

                 String property = (String) i.next();

215

0

                 Object value = beanMap.get(property);

216

0

                 log.error(property + " -> " + value);

217

0

             }

218

219

0

             log.error(beanMap);

220

0

             throw new JellyTagException(e);

221

         }

222

223

         // Properties

224

         //-------------------------------------------------------------------------

225

         /**

226

          * @return the bean that has just been created

227

          */

228

         public Object getBean() {

229

0

             return bean;

230

         }

231

     }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.