1 package org.apache.turbine.services.intake; 2 3 18 19 import java.beans.IntrospectionException ; 20 import java.beans.PropertyDescriptor ; 21 22 import java.io.File ; 23 import java.io.FileInputStream ; 24 import java.io.FileOutputStream ; 25 import java.io.InputStream ; 26 import java.io.ObjectInputStream ; 27 import java.io.ObjectOutputStream ; 28 import java.io.OutputStream ; 29 30 import java.lang.reflect.Method ; 31 32 import java.util.HashMap ; 33 import java.util.HashSet ; 34 import java.util.Iterator ; 35 import java.util.List ; 36 import java.util.Map ; 37 import java.util.Set ; 38 import java.util.Vector ; 39 40 import javax.servlet.ServletConfig ; 41 42 import org.apache.commons.lang.StringUtils; 43 44 import org.apache.commons.logging.Log; 45 import org.apache.commons.logging.LogFactory; 46 47 import org.apache.commons.pool.KeyedObjectPool; 48 import org.apache.commons.pool.KeyedPoolableObjectFactory; 49 import org.apache.commons.pool.impl.StackKeyedObjectPool; 50 51 import org.apache.turbine.Turbine; 52 import org.apache.turbine.services.InitializationException; 53 import org.apache.turbine.services.TurbineBaseService; 54 import org.apache.turbine.services.intake.model.Group; 55 import org.apache.turbine.services.intake.transform.XmlToAppData; 56 import org.apache.turbine.services.intake.xmlmodel.AppData; 57 import org.apache.turbine.services.intake.xmlmodel.XmlGroup; 58 59 68 public class TurbineIntakeService 69 extends TurbineBaseService 70 implements IntakeService 71 { 72 73 private Map groupNames; 74 75 76 private Map groupNameMap; 77 78 79 private Map groupKeyMap; 80 81 82 private Map getterMap; 83 84 85 private Map setterMap; 86 87 88 private Map keyedPools; 89 90 91 private static Log log = LogFactory.getLog(TurbineIntakeService.class); 92 93 97 public TurbineIntakeService() 98 { 99 } 100 101 107 public void init() 108 throws InitializationException 109 { 110 Vector defaultXmlPathes = new Vector (); 111 defaultXmlPathes.add(XML_PATH_DEFAULT); 112 113 List xmlPathes = getConfiguration() 114 .getList(XML_PATH, defaultXmlPathes); 115 116 Map appDataElements = null; 117 118 String serialDataPath = getConfiguration() 119 .getString(SERIAL_XML, SERIAL_XML_DEFAULT); 120 121 if (!serialDataPath.equalsIgnoreCase("none")) 122 { 123 serialDataPath = Turbine.getRealPath(serialDataPath); 124 } 125 else 126 { 127 serialDataPath = null; 128 } 129 130 log.debug("Path for serializing: " + serialDataPath); 131 132 groupNames = new HashMap (); 133 groupKeyMap = new HashMap (); 134 groupNameMap = new HashMap (); 135 getterMap = new HashMap (); 136 setterMap = new HashMap (); 137 keyedPools = new HashMap (); 138 139 if (xmlPathes == null) 140 { 141 String LOAD_ERROR = "No pathes for XML files were specified. " + 142 "Check that the property exists in " + 143 "TurbineResources.props and were loaded."; 144 145 log.error(LOAD_ERROR); 146 throw new InitializationException(LOAD_ERROR); 147 } 148 149 Set xmlFiles = new HashSet (); 150 151 long timeStamp = 0; 152 153 for (Iterator it = xmlPathes.iterator(); it.hasNext();) 154 { 155 String xmlPath = Turbine.getRealPath((String ) it.next()); 157 File xmlFile = new File (xmlPath); 158 159 log.debug("Path for XML File: " + xmlFile); 160 161 if (!xmlFile.canRead()) 162 { 163 String READ_ERR = "Could not read input file " + xmlPath; 164 165 log.error(READ_ERR); 166 throw new InitializationException(READ_ERR); 167 } 168 169 xmlFiles.add(xmlPath); 170 171 log.debug("Added " + xmlPath + " as File to parse"); 172 173 timeStamp = 177 (xmlFile.lastModified() > timeStamp) ? xmlFile.lastModified() : timeStamp; 178 } 179 180 Map serializedMap = loadSerialized(serialDataPath, timeStamp); 181 182 if (serializedMap != null) 183 { 184 appDataElements = serializedMap; 186 log.debug("Using the serialized map"); 187 } 188 else 189 { 190 appDataElements = new HashMap (); 192 193 for (Iterator it = xmlFiles.iterator(); it.hasNext();) 194 { 195 String xmlPath = (String ) it.next(); 196 AppData appData = null; 197 198 log.debug("Now parsing: " + xmlPath); 199 try 200 { 201 XmlToAppData xmlApp = new XmlToAppData(); 202 appData = xmlApp.parseFile(xmlPath); 203 } 204 catch (Exception e) 205 { 206 log.error("Could not parse XML file " + xmlPath, e); 207 208 throw new InitializationException("Could not parse XML file " + 209 xmlPath, e); 210 } 211 212 appDataElements.put(appData, xmlPath); 213 log.debug("Saving appData for " + xmlPath); 214 } 215 216 saveSerialized(serialDataPath, appDataElements); 217 } 218 219 try 220 { 221 for (Iterator it = appDataElements.keySet().iterator(); it.hasNext();) 222 { 223 AppData appData = (AppData) it.next(); 224 225 int maxPooledGroups = 0; 226 List glist = appData.getGroups(); 227 228 String groupPrefix = appData.getGroupPrefix(); 229 230 for (int i = glist.size() - 1; i >= 0; i--) 231 { 232 XmlGroup g = (XmlGroup) glist.get(i); 233 String groupName = g.getName(); 234 235 boolean registerUnqualified = registerGroup(groupName, g, appData, true); 236 237 if (!registerUnqualified) 238 { 239 log.info("Ignored redefinition of Group " + groupName 240 + " or Key " + g.getKey() 241 + " from " + appDataElements.get(appData)); 242 } 243 244 if (groupPrefix != null) 245 { 246 StringBuffer qualifiedName = new StringBuffer (); 247 qualifiedName.append(groupPrefix) 248 .append(':') 249 .append(groupName); 250 251 if (!registerGroup(qualifiedName.toString(), g, appData, !registerUnqualified)) 255 { 256 log.error("Could not register fully qualified name " + qualifiedName 257 + ", maybe two XML files have the same prefix. Ignoring it."); 258 } 259 } 260 261 maxPooledGroups = 262 Math.max(maxPooledGroups, 263 Integer.parseInt(g.getPoolCapacity())); 264 265 } 266 267 KeyedPoolableObjectFactory factory = 268 new Group.GroupFactory(appData); 269 keyedPools.put(appData, new StackKeyedObjectPool(factory, maxPooledGroups)); 270 } 271 272 setInit(true); 273 } 274 catch (Exception e) 275 { 276 throw new InitializationException( 277 "TurbineIntakeService failed to initialize", e); 278 } 279 } 280 281 287 public void init(ServletConfig config) 288 throws InitializationException 289 { 290 init(); 291 } 292 293 303 private boolean registerGroup(String groupName, XmlGroup group, AppData appData, boolean checkKey) 304 { 305 if (groupNames.keySet().contains(groupName)) 306 { 307 return false; 309 } 310 311 boolean keyExists = groupNameMap.keySet().contains(group.getKey()); 312 313 if (checkKey && keyExists) 314 { 315 return false; 317 } 318 319 groupNames.put(groupName, appData); 320 321 groupKeyMap.put(groupName, group.getKey()); 322 323 if (!keyExists) 324 { 325 groupNameMap.put(group.getKey(), groupName); 327 } 328 329 List classNames = group.getMapToObjects(); 330 for (Iterator iter2 = classNames.iterator(); iter2.hasNext();) 331 { 332 String className = (String ) iter2.next(); 333 if (!getterMap.containsKey(className)) 334 { 335 getterMap.put(className, new HashMap ()); 336 setterMap.put(className, new HashMap ()); 337 } 338 } 339 return true; 340 } 341 342 351 private Map loadSerialized(String serialDataPath, long timeStamp) 352 { 353 log.debug("Entered loadSerialized(" 354 + serialDataPath + ", " 355 + timeStamp + ")"); 356 357 if (serialDataPath == null) 358 { 359 return null; 360 } 361 362 File serialDataFile = new File (serialDataPath); 363 364 if (!serialDataFile.exists()) 365 { 366 log.info("No serialized file found, parsing XML"); 367 return null; 368 } 369 370 if (serialDataFile.lastModified() <= timeStamp) 371 { 372 log.info("serialized file too old, parsing XML"); 373 return null; 374 } 375 376 InputStream in = null; 377 Map serialData = null; 378 379 try 380 { 381 in = new FileInputStream (serialDataFile); 382 ObjectInputStream p = new ObjectInputStream (in); 383 Object o = p.readObject(); 384 385 if (o instanceof Map ) 386 { 387 serialData = (Map ) o; 388 } 389 else 390 { 391 log.info("serialized object is not an intake map, ignoring"); 393 in.close(); 394 in = null; 395 serialDataFile.delete(); } 397 } 398 catch (Exception e) 399 { 400 log.error("Serialized File could not be read.", e); 401 402 serialData = null; 405 } 406 finally 407 { 408 try 411 { 412 if (in != null) 413 { 414 in.close(); 415 } 416 } 417 catch (Exception e) 418 { 419 log.error("Exception while closing file", e); 420 } 421 } 422 423 log.info("Loaded serialized map object, ignoring XML"); 424 return serialData; 425 } 426 427 436 private void saveSerialized(String serialDataPath, Map appDataElements) 437 { 438 439 log.debug("Entered saveSerialized(" 440 + serialDataPath + ", appDataElements)"); 441 442 if (serialDataPath == null) 443 { 444 return; 445 } 446 447 File serialData = new File (serialDataPath); 448 449 try 450 { 451 serialData.createNewFile(); 452 serialData.delete(); 453 } 454 catch (Exception e) 455 { 456 log.info("Could not create serialized file " + serialDataPath 457 + ", not serializing the XML data"); 458 return; 459 } 460 461 OutputStream out = null; 462 InputStream in = null; 463 464 try 465 { 466 out = new FileOutputStream (serialDataPath); 468 ObjectOutputStream pout = new ObjectOutputStream (out); 469 pout.writeObject(appDataElements); 470 pout.flush(); 471 472 in = new FileInputStream (serialDataPath); 475 ObjectInputStream pin = new ObjectInputStream (in); 476 Map dummy = (Map ) pin.readObject(); 477 478 log.debug("Serializing successful"); 479 } 480 catch (Exception e) 481 { 482 log.info("Could not write serialized file to " + serialDataPath 483 + ", not serializing the XML data"); 484 } 485 finally 486 { 487 try 488 { 489 if (out != null) 490 { 491 out.close(); 492 } 493 if (in != null) 494 { 495 in.close(); 496 } 497 } 498 catch (Exception e) 499 { 500 log.error("Exception while closing file", e); 501 } 502 } 503 } 504 505 513 public Group getGroup(String groupName) 514 throws IntakeException 515 { 516 Group group = null; 517 518 AppData appData = (AppData) groupNames.get(groupName); 519 520 if (groupName == null) 521 { 522 throw new IntakeException( 523 "Intake TurbineIntakeService.getGroup(groupName) is null"); 524 } 525 if (appData == null) 526 { 527 throw new IntakeException( 528 "Intake TurbineIntakeService.getGroup(groupName): No XML definition for Group " 529 + groupName + " found"); 530 } 531 try 532 { 533 group = (Group) ((KeyedObjectPool) keyedPools.get(appData)).borrowObject(groupName); 534 } 535 catch (Exception e) 536 { 537 throw new IntakeException("Could not get group " + groupName, e); 538 } 539 return group; 540 } 541 542 549 public void releaseGroup(Group instance) 550 throws IntakeException 551 { 552 if (instance != null) 553 { 554 String groupName = instance.getIntakeGroupName(); 555 AppData appData = (AppData) groupNames.get(groupName); 556 557 if (appData == null) 558 { 559 throw new IntakeException( 560 "Intake TurbineIntakeService.releaseGroup(groupName): " 561 + "No XML definition for Group " + groupName + " found"); 562 } 563 564 try 565 { 566 ((KeyedObjectPool) keyedPools.get(appData)).returnObject(groupName, instance); 567 } 568 catch (Exception e) 569 { 570 new IntakeException("Could not get group " + groupName, e); 571 } 572 } 573 } 574 575 582 public int getSize(String groupName) 583 throws IntakeException 584 { 585 AppData appData = (AppData) groupNames.get(groupName); 586 if (appData == null) 587 { 588 throw new IntakeException( 589 "Intake TurbineIntakeService.Size(groupName): No XML definition for Group " 590 + groupName + " found"); 591 } 592 593 KeyedObjectPool kop = (KeyedObjectPool) keyedPools.get(groupName); 594 595 return kop.getNumActive(groupName) 596 + kop.getNumIdle(groupName); 597 } 598 599 604 public String [] getGroupNames() 605 { 606 return (String []) groupNames.keySet().toArray(new String [0]); 607 } 608 609 615 public String getGroupKey(String groupName) 616 { 617 return (String ) groupKeyMap.get(groupName); 618 } 619 620 626 public String getGroupName(String groupKey) 627 { 628 return (String ) groupNameMap.get(groupKey); 629 } 630 631 640 public Method getFieldSetter(String className, String propName) 641 throws ClassNotFoundException , IntrospectionException 642 { 643 Map settersForClassName = (Map ) setterMap.get(className); 644 645 if (settersForClassName == null) 646 { 647 throw new IntrospectionException ("No setter Map for " + className + " available!"); 648 } 649 650 Method setter = (Method ) settersForClassName.get(propName); 651 652 if (setter == null) 653 { 654 PropertyDescriptor pd = null; 655 656 synchronized (setterMap) 657 { 658 try 659 { 660 pd = new PropertyDescriptor (propName, 661 Class.forName(className)); 662 } 663 catch (IntrospectionException ie) 664 { 665 if (log.isWarnEnabled()) 666 { 667 log.warn("Trying to find only a setter for " + propName); 668 } 669 670 pd = new PropertyDescriptor (propName, 671 Class.forName(className), 672 "set" + StringUtils.capitalise(propName), 673 null); } 675 676 setter = pd.getWriteMethod(); 677 settersForClassName.put(propName, setter); 678 679 if (setter == null) 680 { 681 log.error("Intake: setter for '" + propName 682 + "' in class '" + className 683 + "' could not be found."); 684 } 685 } 686 687 if (pd.getReadMethod() != null) 688 { 689 synchronized (getterMap) 692 { 693 Map gettersForClassName = (Map ) getterMap.get(className); 694 695 if (gettersForClassName != null) 696 { 697 try 698 { 699 Method getter = pd.getReadMethod(); 700 if (getter != null) 701 { 702 gettersForClassName.put(propName, getter); 703 } 704 } 705 catch (Exception e) 706 { 707 } 709 } 710 } 711 } 712 } 713 return setter; 714 } 715 716 725 public Method getFieldGetter(String className, String propName) 726 throws ClassNotFoundException , IntrospectionException 727 { 728 Map gettersForClassName = (Map ) getterMap.get(className); 729 730 if (gettersForClassName == null) 731 { 732 throw new IntrospectionException ("No getter Map for " + className + " available!"); 733 } 734 735 Method getter = (Method ) gettersForClassName.get(propName); 736 737 if (getter == null) 738 { 739 PropertyDescriptor pd = null; 740 741 synchronized (getterMap) 742 { 743 try 744 { 745 pd = new PropertyDescriptor (propName, 746 Class.forName(className)); 747 } 748 catch (IntrospectionException ie) 749 { 750 if (log.isWarnEnabled()) 751 { 752 log.warn("Trying to find only a getter for " + propName); 753 } 754 755 pd = new PropertyDescriptor (propName, 756 Class.forName(className), 757 "get" + StringUtils.capitalise(propName), 758 null); } 760 761 getter = pd.getReadMethod(); 762 gettersForClassName.put(propName, getter); 763 764 if (getter == null) 765 { 766 log.error("Intake: getter for '" + propName 767 + "' in class '" + className 768 + "' could not be found."); 769 } 770 } 771 772 if (pd.getWriteMethod() != null) 773 { 774 synchronized (setterMap) 777 { 778 Map settersForClassName = (Map ) getterMap.get(className); 779 780 if (settersForClassName != null) 781 { 782 try 783 { 784 Method setter = pd.getWriteMethod(); 785 if (setter != null) 786 { 787 settersForClassName.put(propName, setter); 788 } 789 } 790 catch (Exception e) 791 { 792 } 794 } 795 } 796 } 797 } 798 return getter; 799 } 800 } 801 | Popular Tags |