View Javadoc

1   //$Id: ArrayCreatorAction.java 351 2008-08-14 20:20:56Z jg_hamburg $
2   /********************************************************************************
3    * DDTUnit, a Datadriven Approach to Unit- and Moduletesting
4    * Copyright (c) 2004, Joerg and Kai Gellien
5    * All rights reserved.
6    *
7    * The Software is provided under the terms of the Common Public License 1.0
8    * as provided with the distribution of DDTUnit in the file cpl-v10.html.
9    * Redistribution and use in source and binary forms, with or without
10   * modification, are permitted provided that the following conditions
11   * are met:
12   *
13   *     + Redistributions of source code must retain the above copyright
14   *       notice, this list of conditions and the following disclaimer.
15   *
16   *     + Redistributions in binary form must reproduce the above
17   *       copyright notice, this list of conditions and the following
18   *       disclaimer in the documentation and/or other materials provided
19   *       with the distribution.
20   *
21   *     + Neither the id of the authors or DDTUnit, nor the
22   *       names of its contributors may be used to endorse or promote
23   *       products derived from this software without specific prior
24   *       written permission.
25   *
26   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29   * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
30   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31   * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32   * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33   * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34   * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35   * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37   ********************************************************************************/
38  package junitx.ddtunit.data.processing;
39  
40  import java.lang.reflect.Array;
41  import java.util.HashMap;
42  import java.util.List;
43  import java.util.Map;
44  
45  import junitx.ddtunit.DDTException;
46  import junitx.ddtunit.data.DDTTestDataException;
47  import junitx.ddtunit.data.TypedObject;
48  
49  import org.slf4j.Logger;
50  import org.slf4j.LoggerFactory;
51  
52  /**
53   * This class contains object state and other information to create object from
54   * SAX event stream.
55   * 
56   * @author jg
57   */
58  public class ArrayCreatorAction extends ActionBase {
59      protected Logger log = LoggerFactory.getLogger(ArrayCreatorAction.class);
60  
61      /**
62       * 
63       * Constructor used as standard constructor to instanciate actions of this
64       * type
65       * 
66       * @param attrMap
67       */
68      public ArrayCreatorAction(Map<String, String> attrMap) {
69          super(attrMap);
70      }
71  
72      /*
73       * (non-Javadoc)
74       * 
75       * @see junitx.ddtunit.parser.ActionBase#process()
76       */
77      public IAction process() {
78          log.debug("process - process new signature for call...");
79          if (!this.successorProcessed) {
80              processNoSuccessor();
81          }
82          IAction rootAction = getPrevious();
83          if (rootAction != null) {
84              String hintValue = rootAction.getHint();
85  
86              if (HintTypes.INTERNAL_MAPENTRY.equals(hintValue)
87                      || HintTypes.FIELDS.equals(hintValue)
88                      || HintTypes.COLLECTION.equals(hintValue)
89                      || HintTypes.ATTRLIST.equals(hintValue)) {
90                  rootAction.processSuccessor(this);
91              } else {
92                  throw new UnsupportedOperationException(
93                          "CollectionCreatorAction does not support hint '"
94                                  + hintValue + "'");
95              }
96          } else {
97              rootAction = this;
98          }
99          // if rootAction is null simply return action -> base object is a
100         // collection
101         pop();
102         // do not forget to process the actual root element
103         return rootAction;
104     }
105 
106     public void processSuccessor(IAction successor) {
107         log.debug("processSuccessor(" + successor + " - START");
108         if (successor != null) {
109             if (HintTypes.FIELDS.equals(successor.getHint())
110                     || HintTypes.COLLECTION.equals(successor.getHint())) {
111                 Map attribMap = new HashMap();
112                 IAction attribListAction = ActionFactory.getAction(
113                     ActionState.ATTRLIST_CREATION, attribMap);
114                 this.insert(attribListAction);
115                 try {
116                     attribListAction.createObject();
117                     // initialize with first list element
118                     ((List) attribListAction.getValue()).add(successor
119                         .getObject());
120                 } catch (Exception ex) {
121                     throw new DDTException("Error on action processing", ex);
122                 }
123             } else if (HintTypes.CONTENT.equals(successor.getHint())) {
124                 String value = successor.getValue().toString();
125                 if (!ContentCreatorAction.CONTENT_NULL.equals(value)) {
126                     try {
127                         int size = Integer.parseInt(value);
128                         instanciateArray(size);
129                     } catch (NumberFormatException ex) {
130                         throw new DDTTestDataException(
131                                 "Must provide an integer as size of array.");
132                     } catch (Exception ex) {
133                         // TODO Auto-generated catch block
134                         ex.printStackTrace();
135                     }
136                 }
137             } else {
138                 List fields = (List) successor.getObject().getValue();
139                 TypedObject field = null;
140                 try {
141                     instanciateArray(fields.size());
142                     for (int count = 0; count < fields.size(); count++) {
143                         field = (TypedObject) fields.get(count);
144                         // provided
145                         ((Object[]) this.getValue())[count] = field.getValue();
146                     }
147                 } catch (Exception ex) {
148                     StringBuffer sb = new StringBuffer(
149                             "Error on setting elements of array.");
150                     throw new DDTException(sb.toString(), ex);
151                 }
152             }
153             if (!getType().startsWith("[L")) {
154                 this.setType(getType());
155             }
156             this.successorProcessed = true;
157         }
158     }
159 
160     /**
161      * @param fields
162      * @throws ClassNotFoundException
163      * @throws Exception
164      */
165     private void instanciateArray(int size) throws ClassNotFoundException {
166         if (this.getValue() == null) {
167             String localType = null;
168             if (getType().startsWith("[L")) {
169                 // cut off "[L" ... ";" from array type
170                 localType = getType().substring(2, getType().length() - 1);
171             } else {
172                 localType = getType();
173             }
174             Class clazz = Class.forName(localType);
175             Object arrayObj = Array.newInstance(clazz, size);
176             this.setValue(arrayObj);
177         }
178     }
179 
180     public void processNoSuccessor() {
181         try {
182             instanciateArray(1);
183             if (getType() != null && !getType().startsWith("[L")) {
184                 setType(getType());
185             }
186         } catch (ClassNotFoundException ex) {
187             StringBuffer sb = new StringBuffer(
188                     "Error on setting elements of array.");
189             throw new DDTException(sb.toString(), ex);
190         }
191     }
192 
193     public void setType(String type) {
194         if (this.injectedObject == null) {
195             inject();
196         }
197         if (type != null && !type.startsWith("[L")) {
198             this.injectedObject.setType("[L" + type + ";");
199         }
200     }
201 
202     /*
203      * (non-Javadoc)
204      * 
205      * @see junitx.ddtunit.parser.ActionBase#inject()
206      */
207 
208     public IAction inject() {
209         String type = (String) this.attrMap.get(ParserConstants.XML_ATTR_TYPE);
210         String id = (String) this.attrMap.get(ParserConstants.XML_ATTR_ID);
211         // check if type is based on java.util.Collection
212         try {
213             if (type == null && ParserConstants.XML_ELEM_ITEM.equals(id)) {
214                 type = TypedObject.UNKNOWN_TYPE;
215             }
216         } catch (Exception ex) {
217             throw new DDTException("Container class '" + type
218                     + "' does not implement java.util.Collection.", ex);
219         }
220         this.injectedObject = new TypedObject(id, type);
221         return this;
222     }
223 
224 }