Source Code Cross Referenced for I18nFactorySet.java in  » Web-Framework » struts-1.3.8 » org » apache » struts » tiles » xmlDefinition » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Web Framework » struts 1.3.8 » org.apache.struts.tiles.xmlDefinition 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * $Id: I18nFactorySet.java 471754 2006-11-06 14:55:09Z husted $
003:         *
004:         * Licensed to the Apache Software Foundation (ASF) under one
005:         * or more contributor license agreements.  See the NOTICE file
006:         * distributed with this work for additional information
007:         * regarding copyright ownership.  The ASF licenses this file
008:         * to you under the Apache License, Version 2.0 (the
009:         * "License"); you may not use this file except in compliance
010:         * with the License.  You may obtain a copy of the License at
011:         *
012:         *  http://www.apache.org/licenses/LICENSE-2.0
013:         *
014:         * Unless required by applicable law or agreed to in writing,
015:         * software distributed under the License is distributed on an
016:         * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017:         * KIND, either express or implied.  See the License for the
018:         * specific language governing permissions and limitations
019:         * under the License.
020:         */
021:
022:        package org.apache.struts.tiles.xmlDefinition;
023:
024:        import java.io.FileNotFoundException;
025:        import java.io.IOException;
026:        import java.io.InputStream;
027:        import java.util.ArrayList;
028:        import java.util.HashMap;
029:        import java.util.Iterator;
030:        import java.util.List;
031:        import java.util.Locale;
032:        import java.util.Map;
033:        import java.util.StringTokenizer;
034:
035:        import javax.servlet.ServletContext;
036:        import javax.servlet.ServletRequest;
037:        import javax.servlet.http.HttpServletRequest;
038:        import javax.servlet.http.HttpSession;
039:
040:        import org.apache.commons.logging.Log;
041:        import org.apache.commons.logging.LogFactory;
042:        import org.apache.struts.tiles.taglib.ComponentConstants;
043:        import org.apache.struts.tiles.DefinitionsFactoryException;
044:        import org.apache.struts.tiles.FactoryNotFoundException;
045:        import org.xml.sax.SAXException;
046:
047:        /**
048:         * Definitions factory.
049:         * This implementation allows to have a set of definition factories.
050:         * There is a main factory and one factory for each file associated to a Locale.
051:         *
052:         * To retrieve a definition, we first search for the appropriate factory using
053:         * the Locale found in session context. If no factory is found, use the
054:         * default one. Then we ask the factory for the definition.
055:         *
056:         * A definition factory file is loaded using main filename extended with locale code
057:         * (ex : <code>templateDefinitions_fr.xml</code>). If no file is found under this name, use default file.
058:         */
059:        public class I18nFactorySet extends FactorySet {
060:
061:            /**
062:             * Commons Logging instance.
063:             */
064:            protected static Log log = LogFactory.getLog(I18nFactorySet.class);
065:
066:            /**
067:             * Config file parameter name.
068:             */
069:            public static final String DEFINITIONS_CONFIG_PARAMETER_NAME = "definitions-config";
070:
071:            /**
072:             * Config file parameter name.
073:             */
074:            public static final String PARSER_DETAILS_PARAMETER_NAME = "definitions-parser-details";
075:
076:            /**
077:             * Config file parameter name.
078:             */
079:            public static final String PARSER_VALIDATE_PARAMETER_NAME = "definitions-parser-validate";
080:
081:            /**
082:             * Possible definition filenames.
083:             */
084:            public static final String DEFAULT_DEFINITION_FILENAMES[] = {
085:                    "/WEB-INF/tileDefinitions.xml",
086:                    "/WEB-INF/componentDefinitions.xml",
087:                    "/WEB-INF/instanceDefinitions.xml" };
088:
089:            /**
090:             * Default filenames extension.
091:             */
092:            public static final String FILENAME_EXTENSION = ".xml";
093:
094:            /**
095:             * Default factory.
096:             */
097:            protected DefinitionsFactory defaultFactory = null;
098:
099:            /**
100:             * XML parser used.
101:             * Attribute is transient to allow serialization. In this implementaiton,
102:             * xmlParser is created each time we need it ;-(.
103:             */
104:            protected transient XmlParser xmlParser;
105:
106:            /**
107:             * Do we want validating parser. Default is <code>false</code>.
108:             * Can be set from servlet config file.
109:             */
110:            protected boolean isValidatingParser = false;
111:
112:            /**
113:             * Parser detail level. Default is 0.
114:             * Can be set from servlet config file.
115:             */
116:            protected int parserDetailLevel = 0;
117:
118:            /**
119:             * Names of files containing instances descriptions.
120:             */
121:            private List filenames = null;
122:
123:            /**
124:             * Collection of already loaded definitions set, referenced by their suffix.
125:             */
126:            private Map loaded = null;
127:
128:            /**
129:             * Parameterless Constructor.
130:             * Method {@link #initFactory} must be called prior to any use of created factory.
131:             */
132:            public I18nFactorySet() {
133:                super ();
134:            }
135:
136:            /**
137:             * Constructor.
138:             * Init the factory by reading appropriate configuration file.
139:             * @param servletContext Servlet context.
140:             * @param properties Map containing all properties.
141:             * @throws FactoryNotFoundException Can't find factory configuration file.
142:             */
143:            public I18nFactorySet(ServletContext servletContext, Map properties)
144:                    throws DefinitionsFactoryException {
145:
146:                initFactory(servletContext, properties);
147:            }
148:
149:            /**
150:             * Initialization method.
151:             * Init the factory by reading appropriate configuration file.
152:             * This method is called exactly once immediately after factory creation in
153:             * case of internal creation (by DefinitionUtil).
154:             * @param servletContext Servlet Context passed to newly created factory.
155:             * @param properties Map of name/property passed to newly created factory. Map can contains
156:             * more properties than requested.
157:             * @throws DefinitionsFactoryException An error occur during initialization.
158:             */
159:            public void initFactory(ServletContext servletContext,
160:                    Map properties) throws DefinitionsFactoryException {
161:
162:                // Set some property values
163:                String value = (String) properties
164:                        .get(PARSER_VALIDATE_PARAMETER_NAME);
165:                if (value != null) {
166:                    isValidatingParser = Boolean.valueOf(value).booleanValue();
167:                }
168:
169:                value = (String) properties.get(PARSER_DETAILS_PARAMETER_NAME);
170:                if (value != null) {
171:                    try {
172:                        parserDetailLevel = Integer.valueOf(value).intValue();
173:
174:                    } catch (NumberFormatException ex) {
175:                        log.error("Bad format for parameter '"
176:                                + PARSER_DETAILS_PARAMETER_NAME
177:                                + "'. Integer expected.");
178:                    }
179:                }
180:
181:                // init factory withappropriate configuration file
182:                // Try to use provided filename, if any.
183:                // If no filename are provided, try to use default ones.
184:                String filename = (String) properties
185:                        .get(DEFINITIONS_CONFIG_PARAMETER_NAME);
186:                if (filename != null) { // Use provided filename
187:                    try {
188:                        initFactory(servletContext, filename);
189:                        if (log.isDebugEnabled()) {
190:                            log.debug("Factory initialized from file '"
191:                                    + filename + "'.");
192:                        }
193:
194:                    } catch (FileNotFoundException ex) { // A filename is specified, throw appropriate error.
195:                        log.error(ex.getMessage() + " : Can't find file '"
196:                                + filename + "'");
197:                        throw new FactoryNotFoundException(ex.getMessage()
198:                                + " : Can't find file '" + filename + "'");
199:                    }
200:
201:                } else { // try each default file names
202:                    for (int i = 0; i < DEFAULT_DEFINITION_FILENAMES.length; i++) {
203:                        filename = DEFAULT_DEFINITION_FILENAMES[i];
204:                        try {
205:                            initFactory(servletContext, filename);
206:                            if (log.isInfoEnabled()) {
207:                                log.info("Factory initialized from file '"
208:                                        + filename + "'.");
209:                            }
210:                        } catch (FileNotFoundException ex) {
211:                            // Do nothing
212:                        }
213:                    }
214:                }
215:
216:            }
217:
218:            /**
219:             * Initialization method.
220:             * Init the factory by reading appropriate configuration file.
221:             * This method is called exactly once immediately after factory creation in
222:             * case of internal creation (by DefinitionUtil).
223:             * @param servletContext Servlet Context passed to newly created factory.
224:             * @param proposedFilename File names, comma separated, to use as  base file names.
225:             * @throws DefinitionsFactoryException An error occur during initialization.
226:             */
227:            protected void initFactory(ServletContext servletContext,
228:                    String proposedFilename)
229:                    throws DefinitionsFactoryException, FileNotFoundException {
230:
231:                // Init list of filenames
232:                StringTokenizer tokenizer = new StringTokenizer(
233:                        proposedFilename, ",");
234:                this .filenames = new ArrayList(tokenizer.countTokens());
235:                while (tokenizer.hasMoreTokens()) {
236:                    this .filenames.add(tokenizer.nextToken().trim());
237:                }
238:
239:                loaded = new HashMap();
240:                defaultFactory = createDefaultFactory(servletContext);
241:                if (log.isDebugEnabled())
242:                    log.debug("default factory:" + defaultFactory);
243:            }
244:
245:            /**
246:             * Get default factory.
247:             * @return Default factory
248:             */
249:            protected DefinitionsFactory getDefaultFactory() {
250:                return defaultFactory;
251:            }
252:
253:            /**
254:             * Create default factory .
255:             * Create InstancesMapper for specified Locale.
256:             * If creation failes, use default mapper and log error message.
257:             * @param servletContext Current servlet context. Used to open file.
258:             * @return Created default definition factory.
259:             * @throws DefinitionsFactoryException If an error occur while creating factory.
260:             * @throws FileNotFoundException if factory can't be loaded from filenames.
261:             */
262:            protected DefinitionsFactory createDefaultFactory(
263:                    ServletContext servletContext)
264:                    throws DefinitionsFactoryException, FileNotFoundException {
265:
266:                XmlDefinitionsSet rootXmlConfig = parseXmlFiles(servletContext,
267:                        "", null);
268:                if (rootXmlConfig == null) {
269:                    throw new FileNotFoundException();
270:                }
271:
272:                rootXmlConfig.resolveInheritances();
273:
274:                if (log.isDebugEnabled()) {
275:                    log.debug(rootXmlConfig);
276:                }
277:
278:                DefinitionsFactory factory = new DefinitionsFactory(
279:                        rootXmlConfig);
280:                if (log.isDebugEnabled()) {
281:                    log.debug("factory loaded : " + factory);
282:                }
283:
284:                return factory;
285:            }
286:
287:            /**
288:             * Extract key that will be used to get the sub factory.
289:             * @param name Name of requested definition
290:             * @param request Current servlet request.
291:             * @param servletContext Current servlet context.
292:             * @return the key or <code>null</code> if not found.
293:             */
294:            protected Object getDefinitionsFactoryKey(String name,
295:                    ServletRequest request, ServletContext servletContext) {
296:
297:                Locale locale = null;
298:                try {
299:                    HttpSession session = ((HttpServletRequest) request)
300:                            .getSession(false);
301:                    if (session != null) {
302:                        locale = (Locale) session
303:                                .getAttribute(ComponentConstants.LOCALE_KEY);
304:                    }
305:
306:                } catch (ClassCastException ex) {
307:                    log.error("I18nFactorySet.getDefinitionsFactoryKey");
308:                    ex.printStackTrace();
309:                }
310:
311:                return locale;
312:            }
313:
314:            /**
315:             * Create a factory for specified key.
316:             * If creation failes, return default factory and log an error message.
317:             * @param key The key.
318:             * @param request Servlet request.
319:             * @param servletContext Servlet context.
320:             * @return Definition factory for specified key.
321:             * @throws DefinitionsFactoryException If an error occur while creating factory.
322:             */
323:            protected DefinitionsFactory createFactory(Object key,
324:                    ServletRequest request, ServletContext servletContext)
325:                    throws DefinitionsFactoryException {
326:
327:                if (key == null) {
328:                    return getDefaultFactory();
329:                }
330:
331:                // Build possible postfixes
332:                List possiblePostfixes = calculateSuffixes((Locale) key);
333:
334:                // Search last postix corresponding to a config file to load.
335:                // First check if something is loaded for this postfix.
336:                // If not, try to load its config.
337:                XmlDefinitionsSet lastXmlFile = null;
338:                DefinitionsFactory factory = null;
339:                String curPostfix = null;
340:                int i = 0;
341:
342:                for (i = possiblePostfixes.size() - 1; i >= 0; i--) {
343:                    curPostfix = (String) possiblePostfixes.get(i);
344:
345:                    // Already loaded ?
346:                    factory = (DefinitionsFactory) loaded.get(curPostfix);
347:                    if (factory != null) { // yes, stop search
348:                        return factory;
349:                    }
350:
351:                    // Try to load it. If success, stop search
352:                    lastXmlFile = parseXmlFiles(servletContext, curPostfix,
353:                            null);
354:                    if (lastXmlFile != null) {
355:                        break;
356:                    }
357:                }
358:
359:                // Have we found a description file ?
360:                // If no, return default one
361:                if (lastXmlFile == null) {
362:                    return getDefaultFactory();
363:                }
364:
365:                // We found something. Need to load base and intermediate files
366:                String lastPostfix = curPostfix;
367:                XmlDefinitionsSet rootXmlConfig = parseXmlFiles(servletContext,
368:                        "", null);
369:                for (int j = 0; j < i; j++) {
370:                    curPostfix = (String) possiblePostfixes.get(j);
371:                    parseXmlFiles(servletContext, curPostfix, rootXmlConfig);
372:                }
373:
374:                rootXmlConfig.extend(lastXmlFile);
375:                rootXmlConfig.resolveInheritances();
376:
377:                factory = new DefinitionsFactory(rootXmlConfig);
378:                loaded.put(lastPostfix, factory);
379:
380:                if (log.isDebugEnabled()) {
381:                    log.debug("factory loaded : " + factory);
382:                }
383:
384:                // return last available found !
385:                return factory;
386:            }
387:
388:            /**
389:             * Calculate the suffixes based on the locale.
390:             * @param locale the locale
391:             */
392:            private List calculateSuffixes(Locale locale) {
393:
394:                List suffixes = new ArrayList(3);
395:                String language = locale.getLanguage();
396:                String country = locale.getCountry();
397:                String variant = locale.getVariant();
398:
399:                StringBuffer suffix = new StringBuffer();
400:                suffix.append('_');
401:                suffix.append(language);
402:                if (language.length() > 0) {
403:                    suffixes.add(suffix.toString());
404:                }
405:
406:                suffix.append('_');
407:                suffix.append(country);
408:                if (country.length() > 0) {
409:                    suffixes.add(suffix.toString());
410:                }
411:
412:                suffix.append('_');
413:                suffix.append(variant);
414:                if (variant.length() > 0) {
415:                    suffixes.add(suffix.toString());
416:                }
417:
418:                return suffixes;
419:
420:            }
421:
422:            /**
423:             * Parse files associated to postix if they exist.
424:             * For each name in filenames, append postfix before file extension,
425:             * then try to load the corresponding file.
426:             * If file doesn't exist, try next one. Each file description is added to
427:             * the XmlDefinitionsSet description.
428:             * The XmlDefinitionsSet description is created only if there is a definition file.
429:             * Inheritance is not resolved in the returned XmlDefinitionsSet.
430:             * If no description file can be opened and no definiion set is provided, return <code>null</code>.
431:             * @param postfix Postfix to add to each description file.
432:             * @param xmlDefinitions Definitions set to which definitions will be added. If <code>null</code>, a definitions
433:             * set is created on request.
434:             * @return XmlDefinitionsSet The definitions set created or passed as parameter.
435:             * @throws DefinitionsFactoryException On errors parsing file.
436:             */
437:            protected XmlDefinitionsSet parseXmlFiles(
438:                    ServletContext servletContext, String postfix,
439:                    XmlDefinitionsSet xmlDefinitions)
440:                    throws DefinitionsFactoryException {
441:
442:                if (postfix != null && postfix.length() == 0) {
443:                    postfix = null;
444:                }
445:
446:                // Iterate throw each file name in list
447:                Iterator i = filenames.iterator();
448:                while (i.hasNext()) {
449:                    String filename = concatPostfix((String) i.next(), postfix);
450:                    xmlDefinitions = parseXmlFile(servletContext, filename,
451:                            xmlDefinitions);
452:                }
453:
454:                return xmlDefinitions;
455:            }
456:
457:            /**
458:             * Parse specified xml file and add definition to specified definitions set.
459:             * This method is used to load several description files in one instances list.
460:             * If filename exists and definition set is <code>null</code>, create a new set. Otherwise, return
461:             * passed definition set (can be <code>null</code>).
462:             * @param servletContext Current servlet context. Used to open file.
463:             * @param filename Name of file to parse.
464:             * @param xmlDefinitions Definitions set to which definitions will be added. If null, a definitions
465:             * set is created on request.
466:             * @return XmlDefinitionsSet The definitions set created or passed as parameter.
467:             * @throws DefinitionsFactoryException On errors parsing file.
468:             */
469:            protected XmlDefinitionsSet parseXmlFile(
470:                    ServletContext servletContext, String filename,
471:                    XmlDefinitionsSet xmlDefinitions)
472:                    throws DefinitionsFactoryException {
473:
474:                try {
475:                    InputStream input = servletContext
476:                            .getResourceAsStream(filename);
477:                    // Try to load using real path.
478:                    // This allow to load config file under websphere 3.5.x
479:                    // Patch proposed Houston, Stephen (LIT) on 5 Apr 2002
480:                    if (null == input) {
481:                        try {
482:                            input = new java.io.FileInputStream(servletContext
483:                                    .getRealPath(filename));
484:                        } catch (Exception e) {
485:                        }
486:                    }
487:
488:                    // If the config isn't in the servlet context, try the class loader
489:                    // which allows the config files to be stored in a jar
490:                    if (input == null) {
491:                        input = getClass().getResourceAsStream(filename);
492:                    }
493:
494:                    // If still nothing found, this mean no config file is associated
495:                    if (input == null) {
496:                        if (log.isDebugEnabled()) {
497:                            log.debug("Can't open file '" + filename + "'");
498:                        }
499:                        return xmlDefinitions;
500:                    }
501:
502:                    // Check if parser already exist.
503:                    // Doesn't seem to work yet.
504:                    //if( xmlParser == null )
505:                    if (true) {
506:                        xmlParser = new XmlParser();
507:                        xmlParser.setValidating(isValidatingParser);
508:                    }
509:
510:                    // Check if definition set already exist.
511:                    if (xmlDefinitions == null) {
512:                        xmlDefinitions = new XmlDefinitionsSet();
513:                    }
514:
515:                    xmlParser.parse(input, xmlDefinitions);
516:
517:                } catch (SAXException ex) {
518:                    if (log.isDebugEnabled()) {
519:                        log.debug("Error while parsing file '" + filename
520:                                + "'.");
521:                        ex.printStackTrace();
522:                    }
523:                    throw new DefinitionsFactoryException(
524:                            "Error while parsing file '" + filename + "'. "
525:                                    + ex.getMessage(), ex);
526:
527:                } catch (IOException ex) {
528:                    throw new DefinitionsFactoryException(
529:                            "IO Error while parsing file '" + filename + "'. "
530:                                    + ex.getMessage(), ex);
531:                }
532:
533:                return xmlDefinitions;
534:            }
535:
536:            /**
537:             * Concat postfix to the name. Take care of existing filename extension.
538:             * Transform the given name "name.ext" to have "name" + "postfix" + "ext".
539:             * If there is no ext, return "name" + "postfix".
540:             * @param name Filename.
541:             * @param postfix Postfix to add.
542:             * @return Concatenated filename.
543:             */
544:            private String concatPostfix(String name, String postfix) {
545:                if (postfix == null) {
546:                    return name;
547:                }
548:
549:                // Search file name extension.
550:                // take care of Unix files starting with .
551:                int dotIndex = name.lastIndexOf(".");
552:                int lastNameStart = name
553:                        .lastIndexOf(java.io.File.pathSeparator);
554:                if (dotIndex < 1 || dotIndex < lastNameStart) {
555:                    return name + postfix;
556:                }
557:
558:                String ext = name.substring(dotIndex);
559:                name = name.substring(0, dotIndex);
560:                return name + postfix + ext;
561:            }
562:
563:            /**
564:             * Return String representation.
565:             * @return String representation.
566:             */
567:            public String toString() {
568:                StringBuffer buff = new StringBuffer("I18nFactorySet : \n");
569:                buff.append("--- default factory ---\n");
570:                buff.append(defaultFactory.toString());
571:                buff.append("\n--- other factories ---\n");
572:                Iterator i = factories.values().iterator();
573:                while (i.hasNext()) {
574:                    buff.append(i.next().toString()).append("---------- \n");
575:                }
576:                return buff.toString();
577:            }
578:
579:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.