View Javadoc
1 package org.apache.turbine.services.intake.model; 2 3 /* ==================================================================== 4 * The Apache Software License, Version 1.1 5 * 6 * Copyright (c) 2001 The Apache Software Foundation. All rights 7 * reserved. 8 * 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 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 21 * 3. The end-user documentation included with the redistribution, 22 * if any, must include the following acknowledgment: 23 * "This product includes software developed by the 24 * Apache Software Foundation (http://www.apache.org/)." 25 * Alternately, this acknowledgment may appear in the software itself, 26 * if and wherever such third-party acknowledgments normally appear. 27 * 28 * 4. The names "Apache" and "Apache Software Foundation" and 29 * "Apache Turbine" must not be used to endorse or promote products 30 * derived from this software without prior written permission. For 31 * written permission, please contact apache@apache.org. 32 * 33 * 5. Products derived from this software may not be called "Apache", 34 * "Apache Turbine", nor may "Apache" appear in their name, without 35 * prior written permission of the Apache Software Foundation. 36 * 37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 38 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 40 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 43 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 44 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 46 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 47 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 48 * SUCH DAMAGE. 49 * ==================================================================== 50 * 51 * This software consists of voluntary contributions made by many 52 * individuals on behalf of the Apache Software Foundation. For more 53 * information on the Apache Software Foundation, please see 54 * <http://www.apache.org/>;. 55 */ 56 57 import java.util.ArrayList; 58 import java.util.HashMap; 59 import java.util.Iterator; 60 import java.util.List; 61 import java.util.Map; 62 import org.apache.turbine.om.Retrievable; 63 import org.apache.turbine.services.intake.TurbineIntake; 64 import org.apache.turbine.services.intake.xmlmodel.XmlField; 65 import org.apache.turbine.services.intake.xmlmodel.XmlGroup; 66 import org.apache.turbine.util.ParameterParser; 67 import org.apache.turbine.util.RunData; 68 import org.apache.turbine.util.TurbineException; 69 import org.apache.turbine.util.pool.Recyclable; 70 71 /*** 72 * Holds a group of Fields 73 * 74 * @version $Id: Group.java,v 1.2 2002/07/11 16:53:27 mpoeschl Exp $ 75 */ 76 public class Group 77 implements Recyclable 78 { 79 public static final String EMPTY = ""; 80 81 /* 82 * An id representing a new object. 83 */ 84 public static final String NEW = "_0"; 85 86 /*** 87 * The key used to represent this group in a parameter. 88 * This key is usually a prefix as part of a field key. 89 */ 90 protected final String gid; 91 92 /*** 93 * The name used in templates and java code to refer to this group. 94 */ 95 protected final String name; 96 97 /*** 98 * The number of Groups with the same name that will be pooled. 99 */ 100 private final int poolCapacity; 101 102 /*** 103 * A map of the fields in this group mapped by field name. 104 */ 105 protected Map fields; 106 107 /*** 108 * Map of the fields by mapToObject 109 */ 110 protected Map mapToObjectFields; 111 112 /*** 113 * An array of fields in this group. 114 */ 115 protected Field[] fieldsArray; 116 117 /*** 118 * The object id used to associate this group to a bean 119 * for one request cycle 120 */ 121 protected String oid; 122 123 /*** 124 * The object containing the request data 125 */ 126 protected RunData data; 127 128 /*** 129 * A flag to help prevent duplicate hidden fields declaring this group. 130 */ 131 protected boolean isDeclared; 132 133 /*** 134 * Constructs a new Group based on the xml specification. Groups are 135 * instantiated and pooled by the IntakeService and should not 136 * be instantiated otherwise. 137 * 138 * @param group a <code>XmlGroup</code> value 139 * @exception Exception if an error occurs in other classes 140 */ 141 public Group(XmlGroup group) 142 throws Exception 143 { 144 gid = group.getKey(); 145 name = group.getName(); 146 poolCapacity = Integer.parseInt(group.getPoolCapacity()); 147 148 List inputFields = group.getFields(); 149 int size = inputFields.size(); 150 fields = new HashMap((int)(1.25*size + 1)); 151 mapToObjectFields = new HashMap((int)(1.25*size + 1)); 152 fieldsArray = new Field[size]; 153 for (int i=size-1; i>=0; i--) 154 { 155 XmlField f = (XmlField)inputFields.get(i); 156 Field field = FieldFactory.getInstance(f, this); 157 fieldsArray[i]= field; 158 fields.put(f.getName(), field); 159 160 // map fields by their mapToObject 161 List tmpFields = (List)mapToObjectFields.get(f.getMapToObject()); 162 if ( tmpFields == null ) 163 { 164 tmpFields = new ArrayList(size); 165 mapToObjectFields.put(f.getMapToObject(), tmpFields); 166 } 167 tmpFields.add(field); 168 } 169 170 // Change the mapToObjectFields values to Field[] 171 Iterator keys = mapToObjectFields.keySet().iterator(); 172 while ( keys.hasNext() ) 173 { 174 Object key = keys.next(); 175 List tmpFields = (List)mapToObjectFields.get(key); 176 mapToObjectFields.put(key, 177 tmpFields.toArray(new Field[tmpFields.size()])); 178 } 179 } 180 181 /*** 182 * Initializes the default Group with parameters from RunData. 183 * 184 * @param data a <code>RunData</code> value 185 * @return this Group 186 */ 187 public Group init(RunData data) throws TurbineException 188 { 189 return init(NEW, data); 190 } 191 192 /*** 193 * Initializes the Group with parameters from RunData 194 * corresponding to key. 195 * 196 * @param data a <code>RunData</code> value 197 * @return this Group 198 */ 199 public Group init(String key, RunData data) 200 throws TurbineException 201 { 202 this.oid = key; 203 this.data = data; 204 for (int i=fieldsArray.length-1; i>=0; i--) 205 { 206 fieldsArray[i].init(data); 207 } 208 return this; 209 } 210 211 212 /*** 213 * Initializes the group with properties from an object. 214 * 215 * @param obj a <code>Persistent</code> value 216 * @return a <code>Group</code> value 217 */ 218 public Group init(Retrievable obj) 219 { 220 this.oid = obj.getQueryKey(); 221 222 Class cls = obj.getClass(); 223 while ( cls != null ) 224 { 225 Field[] flds = (Field[])mapToObjectFields.get(cls.getName()); 226 if ( flds != null ) 227 { 228 for (int i=flds.length-1; i>=0; i--) 229 { 230 flds[i].init(obj); 231 } 232 } 233 234 cls = cls.getSuperclass(); 235 } 236 237 return this; 238 } 239 240 241 /*** 242 * Gets a list of the names of the fields stored in this object. 243 * 244 * @return A String array containing the list of names. 245 */ 246 public String[] getFieldNames() 247 { 248 String nameList[] = new String[fieldsArray.length]; 249 for(int i = 0; i < nameList.length; i++) 250 { 251 nameList[i] = fieldsArray[i].name; 252 } 253 return nameList; 254 } 255 256 257 /*** 258 * Return the name given to this group. The long name is to 259 * avoid conflicts with the get(String key) method. 260 * 261 * @return a <code>String</code> value 262 */ 263 public String getIntakeGroupName() 264 { 265 return name; 266 } 267 268 /*** 269 * Get the number of Group objects that will be pooled. 270 * 271 * @return an <code>int</code> value 272 */ 273 public int getPoolCapacity() 274 { 275 return poolCapacity; 276 } 277 278 /*** 279 * Get the part of the key used to specify the group. 280 * This is specified in the key attribute in the xml file. 281 * 282 * @return a <code>String</code> value 283 */ 284 public String getGID() 285 { 286 return gid; 287 } 288 289 /*** 290 * Get the part of the key that distinguishes a group 291 * from others of the same name. 292 * 293 * @return a <code>String</code> value 294 */ 295 public String getOID() 296 { 297 return oid; 298 } 299 300 /*** 301 * Concatenation of gid and oid. 302 * 303 * @return a <code>String</code> value 304 */ 305 public String getObjectKey() 306 { 307 return gid + oid; 308 } 309 310 /*** 311 * Describe <code>getObjects</code> method here. 312 * 313 * @param pp a <code>ParameterParser</code> value 314 * @return an <code>ArrayList</code> value 315 * @exception TurbineException if an error occurs 316 */ 317 public ArrayList getObjects(RunData data) 318 throws TurbineException 319 { 320 ArrayList objs = null; 321 String[] oids = data.getParameters().getStrings(gid); 322 if (oids != null) 323 { 324 objs = new ArrayList(oids.length); 325 for (int i=oids.length-1; i>=0; i--) 326 { 327 objs.add( TurbineIntake.getGroup(name).init(oids[i], data) ); 328 } 329 } 330 return objs; 331 } 332 333 /*** 334 * Get the Field . 335 * @return Field. 336 */ 337 public Field get(String fieldName) 338 throws TurbineException 339 { 340 if (fields.containsKey(fieldName)) 341 { 342 return (Field)fields.get(fieldName); 343 } 344 else 345 { 346 throw new TurbineException ("Intake Field name: " + fieldName + 347 " not found!"); 348 } 349 } 350 351 /*** 352 * Performs an AND between all the fields in this group. 353 * 354 * @return a <code>boolean</code> value 355 */ 356 public boolean isAllValid() 357 { 358 boolean valid = true; 359 for (int i=fieldsArray.length-1; i>=0; i--) 360 { 361 valid &= fieldsArray[i].isValid(); 362 } 363 return valid; 364 } 365 366 /*** 367 * Calls a setter methods on obj, for fields which have been set. 368 * @exception throws up any exceptions resulting from failure to 369 * check input validity. 370 */ 371 public void setProperties(Object obj) 372 throws TurbineException 373 { 374 Class cls = obj.getClass(); 375 while ( cls != null ) 376 { 377 Field[] flds = (Field[])mapToObjectFields.get(cls.getName()); 378 if ( flds != null ) 379 { 380 for (int i=flds.length-1; i>=0; i--) 381 { 382 flds[i].setProperty(obj); 383 } 384 } 385 386 cls = cls.getSuperclass(); 387 } 388 } 389 390 /*** 391 * Calls getter methods on objects that are known to Intake 392 * so that field values in forms can be initialized from 393 * the values contained in the intake tool. 394 */ 395 public void getProperties(Object obj) 396 throws Exception 397 { 398 Class cls = obj.getClass(); 399 while (cls != null) 400 { 401 Field[] flds = (Field[])mapToObjectFields.get(cls.getName()); 402 if( flds != null ) 403 { 404 for (int i=flds.length-1; i>=0; i--) 405 { 406 flds[i].getProperty(obj); 407 } 408 } 409 410 cls = cls.getSuperclass(); 411 } 412 } 413 414 /*** 415 * Removes references to this group and its fields from the 416 * query parameters 417 */ 418 public void removeFromRequest() 419 { 420 ParameterParser pp = data.getParameters(); 421 String[] groups = pp.getStrings(gid); 422 if ( groups != null ) 423 { 424 pp.remove(gid); 425 for (int i=0; i<groups.length; i++) 426 { 427 if ( groups[i] != null && !groups[i].equals(oid) ) 428 { 429 pp.add(gid,groups[i]); 430 } 431 } 432 for (int i=fieldsArray.length-1; i>=0; i--) 433 { 434 fieldsArray[i].removeFromRequest(); 435 } 436 } 437 } 438 439 /*** 440 * To be used in the event this group is used within multiple 441 * forms within the same template. 442 */ 443 public void resetDeclared() 444 { 445 isDeclared = false; 446 } 447 448 /*** 449 * A xhtml valid hidden input field that notifies intake of the 450 * group's presence. 451 * 452 * @return a <code>String</code> value 453 */ 454 public String getHtmlFormInput() 455 { 456 StringBuffer sb = new StringBuffer(64); 457 appendHtmlFormInput(sb); 458 return sb.toString(); 459 } 460 461 /*** 462 * A xhtml valid hidden input field that notifies intake of the 463 * group's presence. 464 */ 465 public void appendHtmlFormInput(StringBuffer sb) 466 { 467 if ( !isDeclared ) 468 { 469 isDeclared = true; 470 sb.append("<input type=\"hidden\" name=\"") 471 .append(gid) 472 .append("\" value=\"") 473 .append(oid) 474 .append("\"></input>"); 475 } 476 } 477 478 // ****************** Recyclable implementation ************************ 479 480 private boolean disposed; 481 482 /*** 483 * Recycles the object for a new client. Recycle methods with 484 * parameters must be added to implementing object and they will be 485 * automatically called by pool implementations when the object is 486 * taken from the pool for a new client. The parameters must 487 * correspond to the parameters of the constructors of the object. 488 * For new objects, constructors can call their corresponding recycle 489 * methods whenever applicable. 490 * The recycle methods must call their super. 491 */ 492 public void recycle() 493 { 494 disposed = false; 495 } 496 497 /*** 498 * Disposes the object after use. The method is called 499 * when the object is returned to its pool. 500 * The dispose method must call its super. 501 */ 502 public void dispose() 503 { 504 oid = null; 505 data = null; 506 for (int i=fieldsArray.length-1; i>=0; i--) 507 { 508 fieldsArray[i].dispose(); 509 } 510 isDeclared = false; 511 512 disposed = true; 513 } 514 515 /*** 516 * Checks whether the recyclable has been disposed. 517 * @return true, if the recyclable is disposed. 518 */ 519 public boolean isDisposed() 520 { 521 return disposed; 522 } 523 } 524 525

This page was automatically generated by Maven