1 18 19 package org.apache.struts.tiles.xmlDefinition; 20 21 import java.io.FileNotFoundException ; 22 import java.io.IOException ; 23 import java.io.InputStream ; 24 import java.util.ArrayList ; 25 import java.util.HashMap ; 26 import java.util.Iterator ; 27 import java.util.List ; 28 import java.util.Locale ; 29 import java.util.Map ; 30 import java.util.StringTokenizer ; 31 32 import javax.servlet.ServletContext ; 33 import javax.servlet.ServletRequest ; 34 import javax.servlet.http.HttpServletRequest ; 35 import javax.servlet.http.HttpSession ; 36 37 import org.apache.commons.logging.Log; 38 import org.apache.commons.logging.LogFactory; 39 import org.apache.struts.taglib.tiles.ComponentConstants; 40 import org.apache.struts.tiles.DefinitionsFactoryException; 41 import org.apache.struts.tiles.FactoryNotFoundException; 42 import org.xml.sax.SAXException ; 43 44 56 public class I18nFactorySet extends FactorySet { 57 58 61 protected static Log log = LogFactory.getLog(I18nFactorySet.class); 62 63 66 public static final String DEFINITIONS_CONFIG_PARAMETER_NAME = 67 "definitions-config"; 68 69 72 public static final String PARSER_DETAILS_PARAMETER_NAME = 73 "definitions-parser-details"; 74 75 78 public static final String PARSER_VALIDATE_PARAMETER_NAME = 79 "definitions-parser-validate"; 80 81 84 public static final String DEFAULT_DEFINITION_FILENAMES[] = 85 { 86 "/WEB-INF/tileDefinitions.xml", 87 "/WEB-INF/componentDefinitions.xml", 88 "/WEB-INF/instanceDefinitions.xml" }; 89 90 94 private static final int MAX_BUNDLES_SEARCHED = 2; 95 96 99 public static final String FILENAME_EXTENSION = ".xml"; 100 101 104 protected DefinitionsFactory defaultFactory = null; 105 106 111 protected transient XmlParser xmlParser; 112 113 117 protected boolean isValidatingParser = false; 118 119 123 protected int parserDetailLevel = 0; 124 125 128 private List filenames = null; 129 130 133 private Map loaded = null; 134 135 139 public I18nFactorySet() { 140 super(); 141 } 142 143 150 public I18nFactorySet(ServletContext servletContext, Map properties) 151 throws DefinitionsFactoryException { 152 153 initFactory(servletContext, properties); 154 } 155 156 166 public void initFactory(ServletContext servletContext, Map properties) 167 throws DefinitionsFactoryException { 168 169 String value = (String ) properties.get(PARSER_VALIDATE_PARAMETER_NAME); 171 if (value != null) { 172 isValidatingParser = Boolean.valueOf(value).booleanValue(); 173 } 174 175 value = (String ) properties.get(PARSER_DETAILS_PARAMETER_NAME); 176 if (value != null) { 177 try { 178 parserDetailLevel = Integer.valueOf(value).intValue(); 179 180 } catch (NumberFormatException ex) { 181 log.error( 182 "Bad format for parameter '" 183 + PARSER_DETAILS_PARAMETER_NAME 184 + "'. Integer expected."); 185 } 186 } 187 188 String filename = (String ) properties.get(DEFINITIONS_CONFIG_PARAMETER_NAME); 192 if (filename != null) { try { 194 initFactory(servletContext, filename); 195 if (log.isDebugEnabled()) { 196 log.debug("Factory initialized from file '" + filename + "'."); 197 } 198 199 } catch (FileNotFoundException ex) { log.error(ex.getMessage() + " : Can't find file '" + filename + "'"); 201 throw new FactoryNotFoundException( 202 ex.getMessage() + " : Can't find file '" + filename + "'"); 203 } 204 205 } else { for (int i = 0; i < DEFAULT_DEFINITION_FILENAMES.length; i++) { 207 filename = DEFAULT_DEFINITION_FILENAMES[i]; 208 try { 209 initFactory(servletContext, filename); 210 if (log.isInfoEnabled()) { 211 log.info( 212 "Factory initialized from file '" + filename + "'."); 213 } 214 } catch (FileNotFoundException ex) { 215 } 217 } 218 } 219 220 } 221 222 231 protected void initFactory( 232 ServletContext servletContext, 233 String proposedFilename) 234 throws DefinitionsFactoryException, FileNotFoundException { 235 236 StringTokenizer tokenizer = new StringTokenizer (proposedFilename, ","); 238 this.filenames = new ArrayList (tokenizer.countTokens()); 239 while (tokenizer.hasMoreTokens()) { 240 this.filenames.add(tokenizer.nextToken().trim()); 241 } 242 243 loaded = new HashMap (); 244 defaultFactory = createDefaultFactory(servletContext); 245 if (log.isDebugEnabled()) 246 log.debug("default factory:" + defaultFactory); 247 } 248 249 253 protected DefinitionsFactory getDefaultFactory() { 254 return defaultFactory; 255 } 256 257 266 protected DefinitionsFactory createDefaultFactory(ServletContext servletContext) 267 throws DefinitionsFactoryException, FileNotFoundException { 268 269 XmlDefinitionsSet rootXmlConfig = parseXmlFiles(servletContext, "", null); 270 if (rootXmlConfig == null) { 271 throw new FileNotFoundException (); 272 } 273 274 rootXmlConfig.resolveInheritances(); 275 276 if (log.isDebugEnabled()) { 277 log.debug(rootXmlConfig); 278 } 279 280 DefinitionsFactory factory = new DefinitionsFactory(rootXmlConfig); 281 if (log.isDebugEnabled()) { 282 log.debug("factory loaded : " + factory); 283 } 284 285 return factory; 286 } 287 288 295 protected Object getDefinitionsFactoryKey( 296 String name, 297 ServletRequest request, 298 ServletContext servletContext) { 299 300 Locale locale = null; 301 try { 302 HttpSession session = ((HttpServletRequest ) request).getSession(false); 303 if (session != null) { 304 locale = (Locale ) session.getAttribute(ComponentConstants.LOCALE_KEY); 305 } 306 307 } catch (ClassCastException ex) { 308 log.error("I18nFactorySet.getDefinitionsFactoryKey"); 309 ex.printStackTrace(); 310 } 311 312 return locale; 313 } 314 315 324 protected DefinitionsFactory createFactory( 325 Object key, 326 ServletRequest request, 327 ServletContext servletContext) 328 throws DefinitionsFactoryException { 329 330 if (key == null) { 331 return getDefaultFactory(); 332 } 333 334 List possiblePostfixes = calculatePostixes("", (Locale ) key); 336 337 XmlDefinitionsSet lastXmlFile = null; 341 DefinitionsFactory factory = null; 342 String curPostfix = null; 343 int i = 0; 344 345 for (i = possiblePostfixes.size() - 1; i >= 0; i--) { 346 curPostfix = (String ) possiblePostfixes.get(i); 347 348 factory = (DefinitionsFactory) loaded.get(curPostfix); 350 if (factory != null) { return factory; 352 } 353 354 lastXmlFile = parseXmlFiles(servletContext, curPostfix, null); 356 if (lastXmlFile != null) { 357 break; 358 } 359 } 360 361 if (lastXmlFile == null) { 364 return getDefaultFactory(); 365 } 366 367 String lastPostfix = curPostfix; 369 XmlDefinitionsSet rootXmlConfig = parseXmlFiles(servletContext, "", null); 370 for (int j = 0; j < i; j++) { 371 curPostfix = (String ) possiblePostfixes.get(j); 372 parseXmlFiles(servletContext, curPostfix, rootXmlConfig); 373 } 374 375 rootXmlConfig.extend(lastXmlFile); 376 rootXmlConfig.resolveInheritances(); 377 378 factory = new DefinitionsFactory(rootXmlConfig); 379 loaded.put(lastPostfix, factory); 380 381 if (log.isDebugEnabled()) { 382 log.debug("factory loaded : " + factory); 383 } 384 385 return factory; 387 } 388 389 396 private static List calculatePostixes(String baseName, Locale locale) { 397 final List result = new ArrayList (MAX_BUNDLES_SEARCHED); 398 final String language = locale.getLanguage(); 399 final int languageLength = language.length(); 400 final String country = locale.getCountry(); 401 final int countryLength = country.length(); 402 final String variant = locale.getVariant(); 403 final int variantLength = variant.length(); 404 405 if (languageLength + countryLength + variantLength == 0) { 406 return result; 408 } 409 410 final StringBuffer temp = new StringBuffer (baseName); 411 temp.append('_'); 412 temp.append(language); 413 414 if (languageLength > 0) 415 result.add(temp.toString()); 416 417 if (countryLength + variantLength == 0) 418 return result; 419 420 temp.append('_'); 421 temp.append(country); 422 423 if (countryLength > 0) 424 result.add(temp.toString()); 425 426 if (variantLength == 0) { 427 return result; 428 } else { 429 temp.append('_'); 430 temp.append(variant); 431 result.add(temp.toString()); 432 return result; 433 } 434 } 435 436 451 private XmlDefinitionsSet parseXmlFiles( 452 ServletContext servletContext, 453 String postfix, 454 XmlDefinitionsSet xmlDefinitions) 455 throws DefinitionsFactoryException { 456 457 if (postfix != null && postfix.length() == 0) { 458 postfix = null; 459 } 460 461 Iterator i = filenames.iterator(); 463 while (i.hasNext()) { 464 String filename = concatPostfix((String ) i.next(), postfix); 465 xmlDefinitions = parseXmlFile(servletContext, filename, xmlDefinitions); 466 } 467 468 return xmlDefinitions; 469 } 470 471 483 private XmlDefinitionsSet parseXmlFile( 484 ServletContext servletContext, 485 String filename, 486 XmlDefinitionsSet xmlDefinitions) 487 throws DefinitionsFactoryException { 488 489 try { 490 InputStream input = servletContext.getResourceAsStream(filename); 491 if (null == input) { 495 try { 496 input = 497 new java.io.FileInputStream ( 498 servletContext.getRealPath(filename)); 499 } catch (Exception e) { 500 } 501 } 502 503 if (input == null) { 506 input = getClass().getResourceAsStream(filename); 507 } 508 509 if (input == null) { 511 if (log.isDebugEnabled()) { 512 log.debug("Can't open file '" + filename + "'"); 513 } 514 return xmlDefinitions; 515 } 516 517 if (true) { 521 xmlParser = new XmlParser(); 522 xmlParser.setValidating(isValidatingParser); 523 } 524 525 if (xmlDefinitions == null) { 527 xmlDefinitions = new XmlDefinitionsSet(); 528 } 529 530 xmlParser.parse(input, xmlDefinitions); 531 532 } catch (SAXException ex) { 533 if (log.isDebugEnabled()) { 534 log.debug("Error while parsing file '" + filename + "'."); 535 ex.printStackTrace(); 536 } 537 throw new DefinitionsFactoryException( 538 "Error while parsing file '" + filename + "'. " + ex.getMessage(), 539 ex); 540 541 } catch (IOException ex) { 542 throw new DefinitionsFactoryException( 543 "IO Error while parsing file '" + filename + "'. " + ex.getMessage(), 544 ex); 545 } 546 547 return xmlDefinitions; 548 } 549 550 558 private String concatPostfix(String name, String postfix) { 559 if (postfix == null) { 560 return name; 561 } 562 563 int dotIndex = name.lastIndexOf("."); 566 int lastNameStart = name.lastIndexOf(java.io.File.pathSeparator); 567 if (dotIndex < 1 || dotIndex < lastNameStart) { 568 return name + postfix; 569 } 570 571 String ext = name.substring(dotIndex); 572 name = name.substring(0, dotIndex); 573 return name + postfix + ext; 574 } 575 576 580 public String toString() { 581 StringBuffer buff = new StringBuffer ("I18nFactorySet : \n"); 582 buff.append("--- default factory ---\n"); 583 buff.append(defaultFactory.toString()); 584 buff.append("\n--- other factories ---\n"); 585 Iterator i = factories.values().iterator(); 586 while (i.hasNext()) { 587 buff.append(i.next().toString()).append("---------- \n"); 588 } 589 return buff.toString(); 590 } 591 592 } 593 | Popular Tags |