1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package net.sf.jameleon.bean;
18
19 import net.sf.jameleon.XMLable;
20 import net.sf.jameleon.exception.JameleonException;
21
22 import java.util.*;
23
24 /***
25 * This class represents a Functional Point in a TestCase. This is currently used only for test case
26 * documentation generation. Please see the docs on the instance variables for a full understanding of what
27 * a FunctionalPoint is
28 */
29 public class FunctionalPoint implements XMLable, Cloneable {
30 private static final long serialVersionUID = 1L;
31 /***
32 * The name of the developer that wrote this <code>FunctionalPoint</code>
33 */
34 protected String author;
35 /***
36 * The applications supported by this functional point
37 */
38 protected ArrayList applications;
39 /***
40 * The name of the class that this tag represents.
41 */
42 protected String className;
43 /***
44 * The tags to be used in the test case macro language
45 */
46 protected ArrayList tagNames;
47 /***
48 * A short summary about how this functional can be used
49 */
50 protected String description;
51 /***
52 * The first line of the description.
53 */
54 protected String shortDescription;
55 /***
56 * The type of the functional point. Valid values are <code>action</code>,
57 * <code>validation</code>, <code>navigation</code>
58 */
59 protected String type;
60 /***
61 * The description of how the functional point is being used
62 */
63 protected String functionId;
64 /***
65 * A list of attributes that this functional point uses
66 */
67 protected Map attributes;
68 /***
69 * A list of steps that this FunctionalPoint uses during execution
70 */
71 protected ArrayList steps;
72
73 /***
74 * Default constructor only used to initialize variables
75 */
76 public FunctionalPoint() {
77 author = new String();
78 tagNames = new ArrayList();
79 description = new String();
80 shortDescription = new String();
81 type = new String();
82 attributes = new LinkedHashMap();
83 steps = new ArrayList();
84 applications = new ArrayList();
85 className = new String();
86 }
87
88 /***
89 * Adds an <code>Attribute</code> to the list of attributes used by this <cod>FunctionalPoint</code>
90 * @param attr - An attribute used by this <code>FunctionalPoint</code>
91 */
92 public void addAttribute(Attribute attr){
93 if (attr == null || attr.getName() == null || attr.getName().length() < 1) {
94 throw new JameleonException("Attribute must have a name");
95 }
96 attributes.put(attr.getName(), attr);
97 }
98
99 /***
100 * Adds an application to the list of applications supported by this <cod>FunctionalPoint</code>
101 * @param applicationName - The name of the application supported
102 */
103 public void addApplication(String applicationName){
104 if (applicationName != null && applicationName.trim().length() > 0 && !applications.contains(applicationName)) {
105 applications.add(applicationName);
106 }
107 }
108
109 /***
110 * Adds a step to the list of steps required to execute this <cod>FunctionalPoint</code>
111 * @param step - A simple instruction to execute this functional point
112 */
113 public void addStep(String step){
114 steps.add(step);
115 }
116
117 /***
118 * Gets a particular attribute. It first tries by searching for the name (method name or instance name),
119 * then by searching via the contextName
120 * @return an attribute matching the given name or contextName
121 */
122 public Attribute getAttribute(String name){
123 Attribute attr = (Attribute)attributes.get(name);
124 Attribute attrTmp = null;
125 if (attr == null) {
126 Iterator it = attributes.keySet().iterator();
127 while (it.hasNext() && attr == null) {
128 attrTmp = (Attribute)attributes.get(it.next());
129 if (attrTmp.getContextName() != null && attrTmp.getContextName().equals(name)) {
130 attr = attrTmp;
131 }
132 }
133 }
134 return attr;
135 }
136
137 /***
138 * Gets the applications supported by this functional point
139 * @return The applications supported by this functional point
140 */
141 public ArrayList getApplications(){
142 return applications;
143 }
144
145 /***
146 * @return The name of the developer that wrote this <code>FunctionalPoint</code>
147 */
148 public String getAuthor(){
149 return author;
150 }
151
152 /***
153 * Sets the name of the developer that wrote this <code>FunctionalPoint</code>
154 * @param author - The name of the developer that wrote this <code>FunctionalPoint</code>
155 */
156 public void setAuthor(String author){
157 this.author = author;
158 }
159
160 /***
161 * @return The name of the class that represents this <code>FunctionalPoint</code>
162 */
163 public String getClassName(){
164 return className;
165 }
166
167 /***
168 * Sets the name of the class that represents this <code>FunctionalPoint</code>
169 * @param className - the name of the class that represents this <code>FunctionalPoint</code>
170 */
171 public void setClassName(String className){
172 this.className = className;
173 }
174
175 /***
176 * @return The default tag name to be used in the test case macro language
177 */
178 public String getDefaultTagName(){
179 return (tagNames.size() > 0) ? (String)tagNames.get(0) : "";
180 }
181
182 /***
183 * Gets all tag names registered for this functional point
184 * Functional points can have multiple tag names
185 * @return The tag name to be used in the test case macro language
186 */
187 public List getTagNames(){
188 return tagNames;
189 }
190
191 /***
192 * Adds a tag name - a name used in the test case macro language
193 * Functional points can have multiple tag names
194 * @param tagName - The tag name to be used in the test case macro language
195 */
196 public void addTagName(String tagName){
197 tagNames.add(tagName);
198 }
199
200 /***
201 * @return A short summary about how this functional can be used
202 */
203 public String getDescription(){
204 return description;
205 }
206
207 /***
208 * Sets a short summary about how this functional can be used
209 * @param description - A short summary about how this functional can be used
210 */
211 public void setDescription(String description){
212 this.description = description;
213 }
214
215 /***
216 * Gets the first line of the javadoc class comments.
217 * @return The first line of the javadoc class comments.
218 */
219 public String getShortDescription(){
220 return shortDescription;
221 }
222
223 /***
224 * Sets the first line of the description
225 * @param shortDescription - the first line on the javadoc class comment.
226 */
227 public void setShortDescription(String shortDescription){
228 this.shortDescription = shortDescription;
229 }
230
231 /***
232 * @return A short summary about how this functional point is used
233 */
234 public String getFunctionId(){
235 return functionId;
236 }
237
238 /***
239 * Sets a short summary about how this functional point is used
240 * @param functionId - A short summary about how this functional point is used
241 */
242 public void setFunctionId(String functionId){
243 this.functionId = functionId;
244 }
245
246 /***
247 * @return The type of the functional point
248 * @throws JameleonException if the type is set and it isn't <code>action, validation, nor navigation</code>
249 */
250 public String getType() throws JameleonException{
251 if (!( type == null ||
252 "".equals(type) ||
253 "action".equalsIgnoreCase(type) ||
254 "validation".equalsIgnoreCase(type) ||
255 "navigation".equalsIgnoreCase(type) ||
256 "session".equalsIgnoreCase(type)) ) {
257 throw new JameleonException(type +" is not a valid functional point type."+
258 " Only action, validation, and navigation are valid types");
259 }
260 return this.type;
261 }
262
263 /***
264 * Sets he type of the functional point
265 * @param type - Valid values are <code>action</code>, <code>validation</code>, <code>navigation</code>
266 */
267 public void setType(String type){
268 this.type = type;
269 }
270
271 /***
272 * @return A list of attributes that this functional point uses
273 */
274 public Map getAttributes(){
275 return attributes;
276 }
277
278 /***
279 * Sets A list of attributes that this functional point uses
280 * @param attributes A list of attributes that this functional point uses
281 */
282 public void setAttributes(Map attributes){
283 this.attributes = attributes;
284 }
285
286 /***
287 * @return A list of steps that this FunctionalPoint uses during execution
288 */
289 public List getSteps(){
290 return steps;
291 }
292
293 /***
294 * Sets a list of steps that this FunctionalPoint uses during execution
295 * @param steps - A list of steps that this FunctionalPoint uses during execution
296 */
297 public void setSteps(ArrayList steps){
298 this.steps = steps;
299 }
300
301 public Object clone() throws CloneNotSupportedException {
302 FunctionalPoint fp = null;
303 try{
304 fp = (FunctionalPoint)super.clone();
305 fp.applications = (ArrayList) applications.clone();
306 fp.steps = (ArrayList)steps.clone();
307 fp.tagNames = (ArrayList)tagNames.clone();
308 fp.attributes = new LinkedHashMap(attributes.size());
309 Attribute attr;
310 for (Iterator it = attributes.keySet().iterator(); it.hasNext(); ){
311 attr = (Attribute)attributes.get(it.next());
312 attr = (Attribute)attr.clone();
313 fp.addAttribute(attr);
314 }
315 }catch(CloneNotSupportedException cnse){
316 throw new JameleonException("Could not clone this tag " + fp.getDefaultTagName() +":", cnse);
317 }
318 return fp;
319 }
320
321 public FunctionalPoint cloneFP(){
322 FunctionalPoint fp;
323 try{
324 fp = (FunctionalPoint)clone();
325 }catch(CloneNotSupportedException cnse){
326 fp = this;
327 }
328 return fp;
329 }
330
331 public String toXML(){
332 Iterator it = null;
333 StringBuffer str = new StringBuffer();
334 str.append("\t\t<functional-point-info>\n");
335 if (author != null && author.length() > 0) {
336 str.append("\t\t\t<author>").append(author).append("</author>\n");
337 }
338 it = getTagNames().iterator();
339 while (it.hasNext()) {
340 str.append("\t\t\t<tag-name>").append(it.next()).append("</tag-name>\n");
341 }
342 if (description != null && description.length() > 0) {
343 str.append("\t\t\t<description>").append(description).append("</description>\n");
344 }
345 if (functionId != null && functionId.length() > 0) {
346 str.append("\t\t\t<function-id>").append(functionId).append("</function-id>\n");
347 }
348 if (type != null && type.length() > 0) {
349 str.append("\t\t\t<type>").append(type).append("</type>\n");
350 }
351 if (steps.size() > 0) {
352 str.append("\t\t\t<steps>\n");
353 it = steps.iterator();
354 while (it.hasNext()) {
355 str.append("\t\t\t\t<step>").append(it.next()).append("</step>\n");
356 }
357 str.append("\t\t\t</steps>\n");
358 }
359 if (applications.size() > 0) {
360 str.append("\t\t\t<applications>\n");
361 it = applications.iterator();
362 while (it.hasNext()) {
363 str.append("\t\t\t\t<application>").append(it.next()).append("</application>\n");
364 }
365 str.append("\t\t\t</applications>\n");
366 }
367 if (attributes.size() > 0) {
368 it = attributes.keySet().iterator();
369 str.append("\t\t\t<attributes>\n");
370 while (it.hasNext()) {
371 str.append(((XMLable)attributes.get(it.next())).toXML());
372 }
373 str.append("\t\t\t</attributes>\n");
374 }
375 str.append("\t\t</functional-point-info>\n");
376 return str.toString();
377 }
378
379 /***
380 * @return The first (the default) tag name
381 */
382 public String toString(){
383 return getDefaultTagName();
384 }
385
386 public boolean equals(Object obj){
387 boolean equals = false;
388 if (obj instanceof FunctionalPoint) {
389 List otherTagNames = (((FunctionalPoint)obj).getTagNames());
390 equals = getTagNames().size() == otherTagNames.size();
391 for (Iterator it = otherTagNames.iterator(); it.hasNext();) {
392 equals &= getTagNames().contains(it.next());
393 }
394 }
395 return equals;
396 }
397
398 public int hashCode(){
399 return ( getTagNames().size() + attributes.size() + steps.size() );
400 }
401
402 }