001: //$Id: ArrayCreatorAction.java 250 2006-08-25 21:30:26Z jg_hamburg $
002: /********************************************************************************
003: * DDTUnit, a Datadriven Approach to Unit- and Moduletesting
004: * Copyright (c) 2004, Joerg and Kai Gellien
005: * All rights reserved.
006: *
007: * The Software is provided under the terms of the Common Public License 1.0
008: * as provided with the distribution of DDTUnit in the file cpl-v10.html.
009: * Redistribution and use in source and binary forms, with or without
010: * modification, are permitted provided that the following conditions
011: * are met:
012: *
013: * + Redistributions of source code must retain the above copyright
014: * notice, this list of conditions and the following disclaimer.
015: *
016: * + Redistributions in binary form must reproduce the above
017: * copyright notice, this list of conditions and the following
018: * disclaimer in the documentation and/or other materials provided
019: * with the distribution.
020: *
021: * + Neither the id of the authors or DDTUnit, nor the
022: * names of its contributors may be used to endorse or promote
023: * products derived from this software without specific prior
024: * written permission.
025: *
026: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
027: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
028: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
029: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
030: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
031: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
032: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
033: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
034: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
035: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
036: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
037: ********************************************************************************/package junitx.ddtunit.data.processing;
038:
039: import java.lang.reflect.Array;
040: import java.util.HashMap;
041: import java.util.List;
042: import java.util.Map;
043:
044: import junitx.ddtunit.DDTException;
045: import junitx.ddtunit.data.DDTTestDataException;
046: import junitx.ddtunit.data.TypedObject;
047:
048: import org.apache.log4j.Logger;
049:
050: /**
051: * This class contains object state and other information to create object from
052: * SAX event stream.
053: *
054: * @author jg
055: */
056: public class ArrayCreatorAction extends ActionBase {
057: protected Logger log = Logger.getLogger(ArrayCreatorAction.class);
058:
059: /**
060: *
061: * Constructor used as standard constructor to instanciate actions of this
062: * type
063: *
064: * @param attrMap
065: */
066: public ArrayCreatorAction(Map<String, String> attrMap) {
067: super (attrMap);
068: }
069:
070: /*
071: * (non-Javadoc)
072: *
073: * @see junitx.ddtunit.parser.ActionBase#process()
074: */
075: public IAction process() {
076: log.debug("process - process new signature for call...");
077: if (!this .successorProcessed) {
078: processNoSuccessor();
079: }
080: IAction rootAction = getPrevious();
081: if (rootAction != null) {
082: String hintValue = rootAction.getHint();
083:
084: if (HintTypes.INTERNAL_MAPENTRY.equals(hintValue)
085: || HintTypes.FIELDS.equals(hintValue)
086: || HintTypes.COLLECTION.equals(hintValue)
087: || HintTypes.ATTRLIST.equals(hintValue)) {
088: rootAction.processSuccessor(this );
089: } else {
090: throw new UnsupportedOperationException(
091: "CollectionCreatorAction does not support hint '"
092: + hintValue + "'");
093: }
094: } else {
095: rootAction = this ;
096: }
097: // if rootAction is null simply return action -> base object is a
098: // collection
099: pop();
100: // do not forget to process the actual root element
101: return rootAction;
102: }
103:
104: public void processSuccessor(IAction successor) {
105: log.debug("processSuccessor(" + successor + " - START");
106: if (successor != null) {
107: if (HintTypes.FIELDS.equals(successor.getHint())
108: || HintTypes.COLLECTION.equals(successor.getHint())) {
109: Map attribMap = new HashMap();
110: IAction attribListAction = ActionFactory.getAction(
111: ActionState.ATTRLIST_CREATION, attribMap);
112: this .insert(attribListAction);
113: try {
114: attribListAction.createObject();
115: // initialize with first list element
116: ((List) attribListAction.getValue()).add(successor
117: .getObject());
118: } catch (Exception ex) {
119: throw new DDTException(
120: "Error on action processing", ex);
121: }
122: } else if (HintTypes.CONTENT.equals(successor.getHint())) {
123: String value = successor.getValue().toString();
124: if (!ContentCreatorAction.CONTENT_NULL.equals(value)) {
125: try {
126: int size = Integer.parseInt(value);
127: instanciateArray(size);
128: } catch (NumberFormatException ex) {
129: throw new DDTTestDataException(
130: "Must provide an integer as size of array.");
131: } catch (Exception ex) {
132: // TODO Auto-generated catch block
133: ex.printStackTrace();
134: }
135: }
136: } else {
137: List fields = (List) successor.getObject().getValue();
138: TypedObject field = null;
139: try {
140: instanciateArray(fields.size());
141: for (int count = 0; count < fields.size(); count++) {
142: field = (TypedObject) fields.get(count);
143: // provided
144: ((Object[]) this .getValue())[count] = field
145: .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)
166: throws ClassNotFoundException {
167: if (this .getValue() == null) {
168: String localType = null;
169: if (getType().startsWith("[L")) {
170: // cut off "[L" ... ";" from array type
171: localType = getType().substring(2,
172: getType().length() - 1);
173: } else {
174: localType = getType();
175: }
176: Class clazz = Class.forName(localType);
177: Object arrayObj = Array.newInstance(clazz, size);
178: this .setValue(arrayObj);
179: }
180: }
181:
182: public void processNoSuccessor() {
183: try {
184: instanciateArray(1);
185: if (getType() != null && !getType().startsWith("[L")) {
186: setType(getType());
187: }
188: } catch (ClassNotFoundException ex) {
189: StringBuffer sb = new StringBuffer(
190: "Error on setting elements of array.");
191: throw new DDTException(sb.toString(), ex);
192: }
193: }
194:
195: public void setType(String type) {
196: if (this .injectedObject == null) {
197: inject();
198: }
199: if (type != null && !type.startsWith("[L")) {
200: this .injectedObject.setType("[L" + type + ";");
201: }
202: }
203:
204: /*
205: * (non-Javadoc)
206: *
207: * @see junitx.ddtunit.parser.ActionBase#inject()
208: */
209:
210: public IAction inject() {
211: String type = (String) this .attrMap
212: .get(ParserConstants.XML_ATTR_TYPE);
213: String id = (String) this .attrMap
214: .get(ParserConstants.XML_ATTR_ID);
215: // check if type is based on java.util.Collection
216: try {
217: if (type == null
218: && ParserConstants.XML_ELEM_ITEM.equals(id)) {
219: type = TypedObject.UNKNOWN_TYPE;
220: }
221: } catch (Exception ex) {
222: throw new DDTException("Container class '" + type
223: + "' does not implement java.util.Collection.", ex);
224: }
225: this .injectedObject = new TypedObject(id, type);
226: return this;
227: }
228:
229: }
|