1 16 package com.blandware.atleap.webapp.struts; 17 18 import org.apache.commons.logging.Log; 19 import org.apache.commons.logging.LogFactory; 20 import org.apache.struts.taglib.tiles.ComponentConstants; 21 import org.apache.struts.tiles.DefinitionsFactoryException; 22 import org.apache.struts.tiles.FactoryNotFoundException; 23 import org.apache.struts.tiles.NoSuchDefinitionException; 24 import org.apache.struts.tiles.xmlDefinition.DefinitionsFactory; 25 import org.apache.struts.tiles.xmlDefinition.FactorySet; 26 import org.apache.struts.tiles.xmlDefinition.XmlDefinitionsSet; 27 import org.apache.struts.tiles.xmlDefinition.XmlParser; 28 import org.xml.sax.SAXException ; 29 30 import javax.servlet.ServletContext ; 31 import javax.servlet.ServletRequest ; 32 import javax.servlet.http.HttpServletRequest ; 33 import javax.servlet.http.HttpSession ; 34 import java.io.FileNotFoundException ; 35 import java.io.IOException ; 36 import java.io.InputStream ; 37 import java.util.ArrayList ; 38 import java.util.HashMap ; 39 import java.util.Iterator ; 40 import java.util.List ; 41 import java.util.Locale ; 42 import java.util.Map ; 43 import java.util.StringTokenizer ; 44 45 63 public class HeritableI18nFactorySet extends FactorySet { 64 65 68 protected static Log log = LogFactory.getLog(HeritableI18nFactorySet.class); 69 70 73 public static final String DEFINITIONS_CONFIG_PARAMETER_NAME = 74 "definitions-config"; 75 76 79 public static final String PARSER_DETAILS_PARAMETER_NAME = 80 "definitions-parser-details"; 81 82 85 public static final String PARSER_VALIDATE_PARAMETER_NAME = 86 "definitions-parser-validate"; 87 88 91 public static final String DEFAULT_DEFINITION_FILENAMES[] = 92 { 93 "/WEB-INF/tileDefinitions.xml", 94 "/WEB-INF/componentDefinitions.xml", 95 "/WEB-INF/instanceDefinitions.xml"}; 96 97 101 private static final int MAX_BUNDLES_SEARCHED = 2; 102 103 106 public static final String FILENAME_EXTENSION = ".xml"; 107 108 111 protected DefinitionsFactory defaultFactory = null; 112 113 118 protected transient XmlParser xmlParser; 119 120 124 protected boolean isValidatingParser = false; 125 126 130 protected int parserDetailLevel = 0; 131 132 135 private List filenames = null; 136 137 140 private Map loaded = null; 141 142 146 public HeritableI18nFactorySet() { 147 super(); 148 } 149 150 159 public HeritableI18nFactorySet(ServletContext servletContext, Map properties) 160 throws DefinitionsFactoryException { 161 162 initFactory(servletContext, properties); 163 } 164 165 176 public void initFactory(ServletContext servletContext, Map properties) 177 throws DefinitionsFactoryException { 178 179 String value = (String ) properties.get(PARSER_VALIDATE_PARAMETER_NAME); 181 if ( value != null ) { 182 isValidatingParser = Boolean.valueOf(value).booleanValue(); 183 } 184 185 value = (String ) properties.get(PARSER_DETAILS_PARAMETER_NAME); 186 if ( value != null ) { 187 try { 188 parserDetailLevel = Integer.valueOf(value).intValue(); 189 190 } catch ( NumberFormatException ex ) { 191 log.error("Bad format for parameter '" 192 + PARSER_DETAILS_PARAMETER_NAME 193 + "'. Integer expected."); 194 } 195 } 196 197 String filename = (String ) properties.get(DEFINITIONS_CONFIG_PARAMETER_NAME); 201 if ( filename != null ) { try { 203 initFactory(servletContext, filename); 204 if ( log.isDebugEnabled() ) { 205 log.debug("Factory initialized from file '" + filename + "'."); 206 } 207 208 } catch ( FileNotFoundException ex ) { log.error(ex.getMessage() + " : Can't find file '" + filename + "'"); 210 throw new FactoryNotFoundException(ex.getMessage() + " : Can't find file '" + filename + "'"); 211 } 212 213 } else { for ( int i = 0; i < DEFAULT_DEFINITION_FILENAMES.length; i++ ) { 215 filename = DEFAULT_DEFINITION_FILENAMES[i]; 216 try { 217 initFactory(servletContext, filename); 218 if ( log.isInfoEnabled() ) { 219 log.info("Factory initialized from file '" + filename + "'."); 220 } 221 } catch ( FileNotFoundException ex ) { 222 } 224 } 225 } 226 227 } 228 229 239 protected void initFactory(ServletContext servletContext, 240 String proposedFilename) 241 throws DefinitionsFactoryException, FileNotFoundException { 242 243 StringTokenizer tokenizer = new StringTokenizer (proposedFilename, ","); 245 this.filenames = new ArrayList (tokenizer.countTokens()); 246 while ( tokenizer.hasMoreTokens() ) { 247 this.filenames.add(tokenizer.nextToken().trim()); 248 } 249 250 loaded = new HashMap (); 251 defaultFactory = createDefaultFactory(servletContext); 252 if ( log.isDebugEnabled() ) { 253 log.debug("default factory:" + defaultFactory); 254 } 255 } 256 257 262 protected DefinitionsFactory getDefaultFactory() { 263 return defaultFactory; 264 } 265 266 276 protected DefinitionsFactory createDefaultFactory(ServletContext servletContext) 277 throws DefinitionsFactoryException, FileNotFoundException { 278 279 XmlDefinitionsSet rootXmlConfig = parseXmlFiles(servletContext, "", null); 280 if ( rootXmlConfig == null ) { 281 throw new FileNotFoundException (); 282 } 283 284 rootXmlConfig.resolveInheritances(); 285 286 if ( log.isDebugEnabled() ) { 287 log.debug(rootXmlConfig); 288 } 289 290 DefinitionsFactory factory = new HeritableDefinitionsFactory(rootXmlConfig); 291 if ( log.isDebugEnabled() ) { 292 log.debug("factory loaded : " + factory); 293 } 294 295 return factory; 296 } 297 298 306 protected Object getDefinitionsFactoryKey(String name, 307 ServletRequest request, 308 ServletContext servletContext) { 309 310 Locale locale = null; 311 try { 312 HttpSession session = ((HttpServletRequest ) request).getSession(false); 313 if ( session != null ) { 314 locale = (Locale ) session.getAttribute(ComponentConstants.LOCALE_KEY); 315 } 316 317 } catch ( ClassCastException ex ) { 318 log.error("HeritableI18nFactorySet.getDefinitionsFactoryKey"); 319 ex.printStackTrace(); 320 } 321 322 return locale; 323 } 324 325 335 protected DefinitionsFactory createFactory(Object key, 336 ServletRequest request, 337 ServletContext servletContext) 338 throws DefinitionsFactoryException { 339 340 if ( key == null ) { 341 return getDefaultFactory(); 342 } 343 344 List possiblePostfixes = calculatePostfixes("", (Locale ) key); 346 347 XmlDefinitionsSet lastXmlFile = null; 351 DefinitionsFactory factory = null; 352 String curPostfix = null; 353 int i = 0; 354 355 for ( i = possiblePostfixes.size() - 1; i >= 0; i-- ) { 356 curPostfix = (String ) possiblePostfixes.get(i); 357 358 factory = (DefinitionsFactory) loaded.get(curPostfix); 360 if ( factory != null ) { return factory; 362 } 363 364 lastXmlFile = parseXmlFiles(servletContext, curPostfix, null); 366 if ( lastXmlFile != null ) { 367 break; 368 } 369 } 370 371 if ( lastXmlFile == null ) { 374 return getDefaultFactory(); 375 } 376 377 String lastPostfix = curPostfix; 379 XmlDefinitionsSet rootXmlConfig = parseXmlFiles(servletContext, "", null); 380 for ( int j = 0; j < i; j++ ) { 381 curPostfix = (String ) possiblePostfixes.get(j); 382 parseXmlFiles(servletContext, curPostfix, rootXmlConfig); 383 } 384 385 rootXmlConfig.extend(lastXmlFile); 386 rootXmlConfig.resolveInheritances(); 387 388 factory = new HeritableDefinitionsFactory(rootXmlConfig); 389 loaded.put(lastPostfix, factory); 390 391 if ( log.isDebugEnabled() ) { 392 log.debug("factory loaded : " + factory); 393 } 394 395 return factory; 397 } 398 399 407 private static List calculatePostfixes(String baseName, Locale locale) { 408 final List result = new ArrayList (MAX_BUNDLES_SEARCHED); 409 final String language = locale.getLanguage(); 410 final int languageLength = language.length(); 411 final String country = locale.getCountry(); 412 final int countryLength = country.length(); 413 final String variant = locale.getVariant(); 414 final int variantLength = variant.length(); 415 416 if ( languageLength + countryLength + variantLength == 0 ) { 417 return result; 419 } 420 421 final StringBuffer temp = new StringBuffer (baseName); 422 temp.append('_'); 423 temp.append(language); 424 425 if ( languageLength > 0 ) { 426 result.add(temp.toString()); 427 } 428 429 if ( countryLength + variantLength == 0 ) { 430 return result; 431 } 432 433 temp.append('_'); 434 temp.append(country); 435 436 if ( countryLength > 0 ) { 437 result.add(temp.toString()); 438 } 439 440 if ( variantLength == 0 ) { 441 return result; 442 } else { 443 temp.append('_'); 444 temp.append(variant); 445 result.add(temp.toString()); 446 return result; 447 } 448 } 449 450 466 private XmlDefinitionsSet parseXmlFiles(ServletContext servletContext, 467 String postfix, 468 XmlDefinitionsSet xmlDefinitions) 469 throws DefinitionsFactoryException { 470 471 if ( postfix != null && postfix.length() == 0 ) { 472 postfix = null; 473 } 474 475 Iterator i = filenames.iterator(); 477 while ( i.hasNext() ) { 478 String filename = concatPostfix((String ) i.next(), postfix); 479 xmlDefinitions = parseXmlFile(servletContext, filename, xmlDefinitions); 480 } 481 482 return xmlDefinitions; 483 } 484 485 498 private XmlDefinitionsSet parseXmlFile(ServletContext servletContext, 499 String filename, 500 XmlDefinitionsSet xmlDefinitions) 501 throws DefinitionsFactoryException { 502 503 try { 504 InputStream input = servletContext.getResourceAsStream(filename); 505 if ( null == input ) { 509 try { 510 input = 511 new java.io.FileInputStream (servletContext.getRealPath(filename)); 512 } catch ( Exception e ) { 513 } 514 } 515 516 if ( input == null ) { 518 if ( log.isDebugEnabled() ) { 519 log.debug("Can't open file '" + filename + "'"); 520 } 521 return xmlDefinitions; 522 } 523 524 if ( true ) { 528 xmlParser = new XmlParser(); 529 xmlParser.setValidating(isValidatingParser); 530 } 531 532 if ( xmlDefinitions == null ) { 534 xmlDefinitions = new XmlDefinitionsSet(); 535 } 536 537 xmlParser.parse(input, xmlDefinitions); 538 539 } catch ( SAXException ex ) { 540 if ( log.isDebugEnabled() ) { 541 log.debug("Error while parsing file '" + filename + "'."); 542 ex.printStackTrace(); 543 } 544 throw new DefinitionsFactoryException("Error while parsing file '" + filename + "'. " + ex.getMessage(), 545 ex); 546 547 } catch ( IOException ex ) { 548 throw new DefinitionsFactoryException("IO Error while parsing file '" + filename + "'. " + ex.getMessage(), 549 ex); 550 } 551 552 return xmlDefinitions; 553 } 554 555 564 private String concatPostfix(String name, String postfix) { 565 if ( postfix == null ) { 566 return name; 567 } 568 569 int dotIndex = name.lastIndexOf("."); 572 int lastNameStart = name.lastIndexOf(java.io.File.pathSeparator); 573 if ( dotIndex < 1 || dotIndex < lastNameStart ) { 574 return name + postfix; 575 } 576 577 String ext = name.substring(dotIndex); 578 name = name.substring(0, dotIndex); 579 return name + postfix + ext; 580 } 581 582 587 public String toString() { 588 StringBuffer buff = new StringBuffer ("I18nFactorySet : \n"); 589 buff.append("--- default factory ---\n"); 590 buff.append(defaultFactory.toString()); 591 buff.append("\n--- other factories ---\n"); 592 Iterator i = factories.values().iterator(); 593 while ( i.hasNext() ) { 594 buff.append(i.next().toString()).append("---------- \n"); 595 } 596 return buff.toString(); 597 } 598 599 600 601 602 609 public Map getDefinitions(ServletRequest request, ServletContext servletContext) 610 throws NoSuchDefinitionException, DefinitionsFactoryException { 611 if ( factories == null ) { 612 throw new FactoryNotFoundException("No definitions factory defined"); 613 } 614 615 Object key = getDefinitionsFactoryKey(null, request, servletContext); 616 HeritableDefinitionsFactory factory = (HeritableDefinitionsFactory) getFactory(key, request, servletContext); 617 return factory.getDefinitions(); 618 } 619 620 621 } 622 | Popular Tags |