Source Code Cross Referenced for TraxProcessor.java in  » Content-Management-System » apache-lenya-2.0 » org » apache » cocoon » components » xslt » 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 » Content Management System » apache lenya 2.0 » org.apache.cocoon.components.xslt 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one or more
003:         * contributor license agreements.  See the NOTICE file distributed with
004:         * this work for additional information regarding copyright ownership.
005:         * The ASF licenses this file to You under the Apache License, Version 2.0
006:         * (the "License"); you may not use this file except in compliance with
007:         * the License.  You may obtain a copy of the License at
008:         *
009:         *      http://www.apache.org/licenses/LICENSE-2.0
010:         *
011:         * Unless required by applicable law or agreed to in writing, software
012:         * distributed under the License is distributed on an "AS IS" BASIS,
013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         * See the License for the specific language governing permissions and
015:         * limitations under the License.
016:         */
017:        package org.apache.cocoon.components.xslt;
018:
019:        import java.io.File;
020:        import java.io.IOException;
021:        import java.io.InputStream;
022:        import java.lang.reflect.Method;
023:        import java.util.ArrayList;
024:        import java.util.HashMap;
025:        import java.util.List;
026:        import java.util.Map;
027:
028:        import javax.xml.transform.Result;
029:        import javax.xml.transform.Templates;
030:        import javax.xml.transform.Transformer;
031:        import javax.xml.transform.TransformerException;
032:        import javax.xml.transform.TransformerFactory;
033:        import javax.xml.transform.URIResolver;
034:        import javax.xml.transform.sax.SAXTransformerFactory;
035:        import javax.xml.transform.sax.TemplatesHandler;
036:        import javax.xml.transform.sax.TransformerHandler;
037:        import javax.xml.transform.stream.StreamSource;
038:
039:        import org.apache.avalon.excalibur.pool.Recyclable;
040:        import org.apache.avalon.framework.activity.Disposable;
041:        import org.apache.avalon.framework.activity.Initializable;
042:        import org.apache.avalon.framework.logger.AbstractLogEnabled;
043:        import org.apache.avalon.framework.parameters.ParameterException;
044:        import org.apache.avalon.framework.parameters.Parameterizable;
045:        import org.apache.avalon.framework.parameters.Parameters;
046:        import org.apache.avalon.framework.service.ServiceException;
047:        import org.apache.avalon.framework.service.ServiceManager;
048:        import org.apache.avalon.framework.service.Serviceable;
049:        import org.apache.commons.lang.BooleanUtils;
050:        import org.apache.excalibur.source.Source;
051:        import org.apache.excalibur.source.SourceException;
052:        import org.apache.excalibur.source.SourceResolver;
053:        import org.apache.excalibur.source.SourceValidity;
054:        import org.apache.excalibur.source.impl.validity.AggregatedValidity;
055:        import org.apache.excalibur.store.Store;
056:        import org.apache.excalibur.xml.sax.XMLizable;
057:        import org.apache.excalibur.xml.xslt.XSLTProcessor;
058:        import org.apache.excalibur.xml.xslt.XSLTProcessorException;
059:        import org.apache.excalibur.xmlizer.XMLizer;
060:        import org.xml.sax.ContentHandler;
061:        import org.xml.sax.InputSource;
062:        import org.xml.sax.SAXException;
063:        import org.xml.sax.XMLFilter;
064:
065:        /**
066:         * Adaptation of Excalibur's XSLTProcessor implementation to allow for better
067:         * error reporting.
068:         * 
069:         * @version $Id: TraxProcessor.java 440004 2006-09-04 10:03:19Z anathaniel $
070:         * @since 2.1.8
071:         */
072:
073:        public class TraxProcessor extends AbstractLogEnabled implements 
074:                XSLTProcessor, Serviceable, Initializable, Disposable,
075:                Parameterizable, Recyclable, URIResolver {
076:            /** The store service instance */
077:            protected Store m_store;
078:
079:            /** The configured transformer factory to use */
080:            protected String m_transformerFactory;
081:
082:            /** The trax TransformerFactory this component uses */
083:            protected SAXTransformerFactory m_factory;
084:
085:            /** The default TransformerFactory used by this component */
086:            protected SAXTransformerFactory m_defaultFactory;
087:
088:            /** Is the store turned on? (default is off) */
089:            protected boolean m_useStore;
090:
091:            /** Is incremental processing turned on? (default for Xalan: no) */
092:            protected boolean m_incrementalProcessing;
093:
094:            /** Resolver used to resolve XSLT document() calls, imports and includes */
095:            protected SourceResolver m_resolver;
096:
097:            /** Check included stylesheets */
098:            protected boolean m_checkIncludes;
099:
100:            /** Map of pairs of System ID's / validities of the included stylesheets */
101:            protected Map m_includesMap = new HashMap();
102:
103:            protected XMLizer m_xmlizer;
104:
105:            /** The ServiceManager */
106:            protected ServiceManager m_manager;
107:
108:            /**
109:             * Compose. Try to get the store
110:             * 
111:             * @avalon.service interface="XMLizer"
112:             * @avalon.service interface="SourceResolver"
113:             * @avalon.service interface="Store/TransientStore" optional="true"
114:             */
115:            public void service(final ServiceManager manager)
116:                    throws ServiceException {
117:                m_manager = manager;
118:                m_xmlizer = (XMLizer) m_manager.lookup(XMLizer.ROLE);
119:                m_resolver = (SourceResolver) m_manager
120:                        .lookup(SourceResolver.ROLE);
121:
122:                if (m_manager.hasService(Store.TRANSIENT_STORE)) {
123:                    m_store = (Store) m_manager.lookup(Store.TRANSIENT_STORE);
124:                }
125:            }
126:
127:            /**
128:             * Initialize
129:             */
130:            public void initialize() throws Exception {
131:                m_factory = getTransformerFactory(m_transformerFactory);
132:                m_defaultFactory = m_factory;
133:            }
134:
135:            /**
136:             * Disposable
137:             */
138:            public void dispose() {
139:                if (null != m_manager) {
140:                    m_manager.release(m_store);
141:                    m_manager.release(m_resolver);
142:                    m_manager.release(m_xmlizer);
143:                    m_manager = null;
144:                }
145:                m_xmlizer = null;
146:                m_store = null;
147:                m_resolver = null;
148:            }
149:
150:            /**
151:             * Configure the component
152:             */
153:            public void parameterize(final Parameters params)
154:                    throws ParameterException {
155:                m_useStore = params.getParameterAsBoolean("use-store",
156:                        this .m_useStore);
157:                m_incrementalProcessing = params.getParameterAsBoolean(
158:                        "incremental-processing", this .m_incrementalProcessing);
159:                m_transformerFactory = params.getParameter(
160:                        "transformer-factory", null);
161:                m_checkIncludes = params.getParameterAsBoolean(
162:                        "check-includes", true);
163:                if (!m_useStore) {
164:                    // release the store, if we don't need it anymore
165:                    m_manager.release(m_store);
166:                    m_store = null;
167:                } else if (null == m_store) {
168:                    final String message = "XSLTProcessor: use-store is set to true, "
169:                            + "but unable to aquire the Store.";
170:                    throw new ParameterException(message);
171:                }
172:            }
173:
174:            /**
175:             * Set the transformer factory used by this component
176:             */
177:            public void setTransformerFactory(final String classname) {
178:                m_factory = getTransformerFactory(classname);
179:            }
180:
181:            /**
182:             * @see org.apache.excalibur.xml.xslt.XSLTProcessor#getTransformerHandler(org.apache.excalibur.source.Source)
183:             */
184:            public TransformerHandler getTransformerHandler(
185:                    final Source stylesheet) throws XSLTProcessorException {
186:                return getTransformerHandler(stylesheet, null);
187:            }
188:
189:            /**
190:             * @see org.apache.excalibur.xml.xslt.XSLTProcessor#getTransformerHandler(org.apache.excalibur.source.Source,
191:             *      org.xml.sax.XMLFilter)
192:             */
193:            public TransformerHandler getTransformerHandler(
194:                    final Source stylesheet, final XMLFilter filter)
195:                    throws XSLTProcessorException {
196:                final XSLTProcessor.TransformerHandlerAndValidity validity = getTransformerHandlerAndValidity(
197:                        stylesheet, filter);
198:                return validity.getTransfomerHandler();
199:            }
200:
201:            public TransformerHandlerAndValidity getTransformerHandlerAndValidity(
202:                    final Source stylesheet) throws XSLTProcessorException {
203:                return getTransformerHandlerAndValidity(stylesheet, null);
204:            }
205:
206:            public TransformerHandlerAndValidity getTransformerHandlerAndValidity(
207:                    Source stylesheet, XMLFilter filter)
208:                    throws XSLTProcessorException {
209:
210:                final String id = stylesheet.getURI();
211:                TransformerHandlerAndValidity handlerAndValidity;
212:
213:                try {
214:                    handlerAndValidity = getTemplates(stylesheet, id);
215:                    if (handlerAndValidity != null) {
216:                        if (getLogger().isDebugEnabled()) {
217:                            getLogger().debug("Reusing Templates for " + id);
218:                        }
219:                        return handlerAndValidity;
220:                    }
221:                } catch (Exception e) {
222:                    throw new XSLTProcessorException(
223:                            "Error retrieving template", e);
224:                }
225:
226:                TraxErrorListener errorListener = new TraxErrorListener(
227:                        getLogger(), stylesheet.getURI());
228:                try {
229:                    if (getLogger().isDebugEnabled()) {
230:                        getLogger().debug("Creating new Templates for " + id);
231:                    }
232:
233:                    m_factory.setErrorListener(errorListener);
234:
235:                    // Create a Templates ContentHandler to handle parsing of the
236:                    // stylesheet.
237:                    TemplatesHandler templatesHandler = m_factory
238:                            .newTemplatesHandler();
239:
240:                    // Set the system ID for the template handler since some
241:                    // TrAX implementations (XSLTC) rely on this in order to obtain
242:                    // a meaningful identifier for the Templates instances.
243:                    templatesHandler.setSystemId(id);
244:                    if (filter != null) {
245:                        filter.setContentHandler(templatesHandler);
246:                    }
247:
248:                    if (getLogger().isDebugEnabled()) {
249:                        getLogger().debug(
250:                                "Source = " + stylesheet
251:                                        + ", templatesHandler = "
252:                                        + templatesHandler);
253:                    }
254:
255:                    // Initialize List for included validities
256:                    SourceValidity validity = stylesheet.getValidity();
257:                    if (validity != null && m_checkIncludes) {
258:                        m_includesMap.put(id, new ArrayList());
259:                    }
260:
261:                    try {
262:                        // Process the stylesheet.
263:                        sourceToSAX(stylesheet,
264:                                filter != null ? (ContentHandler) filter
265:                                        : (ContentHandler) templatesHandler);
266:
267:                        // Get the Templates object (generated during the parsing of
268:                        // the stylesheet) from the TemplatesHandler.
269:                        final Templates template = templatesHandler
270:                                .getTemplates();
271:
272:                        if (null == template) {
273:                            throw new XSLTProcessorException(
274:                                    "Unable to create templates for stylesheet: "
275:                                            + stylesheet.getURI());
276:                        }
277:
278:                        // Must set base for Xalan stylesheet.
279:                        // Otherwise document('') in logicsheet causes NPE.
280:                        Class clazz = template.getClass();
281:                        if (clazz.getName().equals(
282:                                "org.apache.xalan.templates.StylesheetRoot")) {
283:                            Method method = clazz.getMethod("setHref",
284:                                    new Class[] { String.class });
285:                            method.invoke(template, new Object[] { id });
286:                        }
287:
288:                        putTemplates(template, stylesheet, id);
289:
290:                        // Create transformer handler
291:                        final TransformerHandler handler = m_factory
292:                                .newTransformerHandler(template);
293:                        handler.getTransformer().setErrorListener(
294:                                new TraxErrorListener(getLogger(), stylesheet
295:                                        .getURI()));
296:                        handler.getTransformer().setURIResolver(this );
297:
298:                        // Create aggregated validity
299:                        AggregatedValidity aggregated = null;
300:                        if (validity != null && m_checkIncludes) {
301:                            List includes = (List) m_includesMap.get(id);
302:                            if (includes != null) {
303:                                aggregated = new AggregatedValidity();
304:                                aggregated.add(validity);
305:                                for (int i = includes.size() - 1; i >= 0; i--) {
306:                                    aggregated
307:                                            .add((SourceValidity) ((Object[]) includes
308:                                                    .get(i))[1]);
309:                                }
310:                                validity = aggregated;
311:                            }
312:                        }
313:
314:                        // Create result
315:                        handlerAndValidity = new MyTransformerHandlerAndValidity(
316:                                handler, validity);
317:                    } finally {
318:                        if (m_checkIncludes)
319:                            m_includesMap.remove(id);
320:                    }
321:
322:                    return handlerAndValidity;
323:                } catch (Exception e) {
324:                    Throwable realEx = errorListener.getThrowable();
325:                    if (realEx == null)
326:                        realEx = e;
327:
328:                    if (realEx instanceof  RuntimeException) {
329:                        throw (RuntimeException) realEx;
330:                    }
331:
332:                    if (realEx instanceof  XSLTProcessorException) {
333:                        throw (XSLTProcessorException) realEx;
334:                    }
335:
336:                    throw new XSLTProcessorException(
337:                            "Exception when creating Transformer from "
338:                                    + stylesheet.getURI(), realEx);
339:                }
340:            }
341:
342:            protected void sourceToSAX(Source source, ContentHandler handler)
343:                    throws SAXException, IOException, SourceException {
344:                if (source instanceof  XMLizable) {
345:                    ((XMLizable) source).toSAX(handler);
346:                } else {
347:                    final InputStream inputStream = source.getInputStream();
348:                    final String mimeType = source.getMimeType();
349:                    final String systemId = source.getURI();
350:                    m_xmlizer.toSAX(inputStream, mimeType, systemId, handler);
351:                }
352:            }
353:
354:            public void transform(final Source source, final Source stylesheet,
355:                    final Parameters params, final Result result)
356:                    throws XSLTProcessorException {
357:                try {
358:                    if (getLogger().isDebugEnabled()) {
359:                        getLogger().debug(
360:                                "Transform source = " + source
361:                                        + ", stylesheet = " + stylesheet
362:                                        + ", parameters = " + params
363:                                        + ", result = " + result);
364:                    }
365:                    final TransformerHandler handler = getTransformerHandler(stylesheet);
366:                    if (params != null) {
367:                        final Transformer transformer = handler
368:                                .getTransformer();
369:                        transformer.clearParameters();
370:                        String[] names = params.getNames();
371:                        for (int i = names.length - 1; i >= 0; i--) {
372:                            transformer.setParameter(names[i], params
373:                                    .getParameter(names[i]));
374:                        }
375:                    }
376:
377:                    handler.setResult(result);
378:                    sourceToSAX(source, handler);
379:                    if (getLogger().isDebugEnabled()) {
380:                        getLogger().debug("Transform done");
381:                    }
382:                } catch (SAXException e) {
383:                    // Unwrapping the exception will "remove" the real cause with
384:                    // never Xalan versions and makes the exception message unusable
385:                    final String message = "Error in running Transformation";
386:                    throw new XSLTProcessorException(message, e);
387:                    /*
388:                     * if( e.getException() == null ) { final String message = "Error in
389:                     * running Transformation"; throw new XSLTProcessorException(
390:                     * message, e ); } else { final String message = "Got SAXException.
391:                     * Rethrowing cause exception."; getLogger().debug( message, e );
392:                     * throw new XSLTProcessorException( "Error in running
393:                     * Transformation", e.getException() ); }
394:                     */
395:                } catch (Exception e) {
396:                    final String message = "Error in running Transformation";
397:                    throw new XSLTProcessorException(message, e);
398:                }
399:            }
400:
401:            /**
402:             * Get the TransformerFactory associated with the given classname. If the
403:             * class can't be found or the given class doesn't implement the required
404:             * interface, the default factory is returned.
405:             */
406:            private SAXTransformerFactory getTransformerFactory(
407:                    String factoryName) {
408:                SAXTransformerFactory _factory;
409:
410:                if (null == factoryName) {
411:                    _factory = (SAXTransformerFactory) TransformerFactory
412:                            .newInstance();
413:                } else {
414:                    try {
415:                        ClassLoader loader = Thread.currentThread()
416:                                .getContextClassLoader();
417:                        if (loader == null) {
418:                            loader = getClass().getClassLoader();
419:                        }
420:                        _factory = (SAXTransformerFactory) loader.loadClass(
421:                                factoryName).newInstance();
422:                    } catch (ClassNotFoundException cnfe) {
423:                        getLogger()
424:                                .error(
425:                                        "Cannot find the requested TrAX factory '"
426:                                                + factoryName
427:                                                + "'. Using default TrAX Transformer Factory instead.");
428:                        if (m_factory != null)
429:                            return m_factory;
430:                        _factory = (SAXTransformerFactory) TransformerFactory
431:                                .newInstance();
432:                    } catch (ClassCastException cce) {
433:                        getLogger()
434:                                .error(
435:                                        "The indicated class '"
436:                                                + factoryName
437:                                                + "' is not a TrAX Transformer Factory. Using default TrAX Transformer Factory instead.");
438:                        if (m_factory != null)
439:                            return m_factory;
440:                        _factory = (SAXTransformerFactory) TransformerFactory
441:                                .newInstance();
442:                    } catch (Exception e) {
443:                        getLogger()
444:                                .error(
445:                                        "Error found loading the requested TrAX Transformer Factory '"
446:                                                + factoryName
447:                                                + "'. Using default TrAX Transformer Factory instead.");
448:                        if (m_factory != null)
449:                            return m_factory;
450:                        _factory = (SAXTransformerFactory) TransformerFactory
451:                                .newInstance();
452:                    }
453:                }
454:
455:                _factory.setErrorListener(new TraxErrorListener(getLogger(),
456:                        null));
457:                _factory.setURIResolver(this );
458:
459:                // FIXME (SM): implementation-specific parameter passing should be
460:                // made more extensible.
461:                if (_factory.getClass().getName().equals(
462:                        "org.apache.xalan.processor.TransformerFactoryImpl")) {
463:                    _factory.setAttribute(
464:                            "http://xml.apache.org/xalan/features/incremental",
465:                            BooleanUtils
466:                                    .toBooleanObject(m_incrementalProcessing));
467:                }
468:                // SAXON 8 will not report errors unless version warning is set to false.
469:                if (_factory.getClass().getName().equals(
470:                        "net.sf.saxon.TransformerFactoryImpl")) {
471:                    _factory.setAttribute(
472:                            "http://saxon.sf.net/feature/version-warning",
473:                            Boolean.FALSE);
474:                }
475:
476:                return _factory;
477:            }
478:
479:            private TransformerHandlerAndValidity getTemplates(
480:                    Source stylesheet, String id) throws IOException,
481:                    TransformerException {
482:                if (!m_useStore) {
483:                    return null;
484:                }
485:
486:                // we must augment the template ID with the factory classname since one
487:                // transformer implementation cannot handle the instances of a
488:                // template created by another one.
489:                String key = "XSLTTemplate: " + id + '('
490:                        + m_factory.getClass().getName() + ')';
491:
492:                if (getLogger().isDebugEnabled()) {
493:                    getLogger().debug("getTemplates: stylesheet " + id);
494:                }
495:
496:                SourceValidity newValidity = stylesheet.getValidity();
497:
498:                // Only stylesheets with validity are stored
499:                if (newValidity == null) {
500:                    // Remove an old template
501:                    m_store.remove(key);
502:                    return null;
503:                }
504:
505:                // Stored is an array of the templates and the caching time and list of
506:                // includes
507:                Object[] templateAndValidityAndIncludes = (Object[]) m_store
508:                        .get(key);
509:                if (templateAndValidityAndIncludes == null) {
510:                    // Templates not found in cache
511:                    return null;
512:                }
513:
514:                // Check template modification time
515:                SourceValidity storedValidity = (SourceValidity) templateAndValidityAndIncludes[1];
516:                int valid = storedValidity.isValid();
517:                boolean isValid;
518:                if (valid == 0) {
519:                    valid = storedValidity.isValid(newValidity);
520:                    isValid = (valid == 1);
521:                } else {
522:                    isValid = (valid == 1);
523:                }
524:                if (!isValid) {
525:                    m_store.remove(key);
526:                    return null;
527:                }
528:
529:                // Check includes
530:                if (m_checkIncludes) {
531:                    AggregatedValidity aggregated = null;
532:                    List includes = (List) templateAndValidityAndIncludes[2];
533:                    if (includes != null) {
534:                        aggregated = new AggregatedValidity();
535:                        aggregated.add(storedValidity);
536:
537:                        for (int i = includes.size() - 1; i >= 0; i--) {
538:                            // Every include stored as pair of source ID and validity
539:                            Object[] pair = (Object[]) includes.get(i);
540:                            storedValidity = (SourceValidity) pair[1];
541:                            aggregated.add(storedValidity);
542:
543:                            valid = storedValidity.isValid();
544:                            isValid = false;
545:                            if (valid == 0) {
546:                                Source includedSource = null;
547:                                try {
548:                                    includedSource = m_resolver
549:                                            .resolveURI((String) pair[0]);
550:                                    SourceValidity included = includedSource
551:                                            .getValidity();
552:                                    if (included != null) {
553:                                        valid = storedValidity
554:                                                .isValid(included);
555:                                        isValid = (valid == 1);
556:                                    }
557:                                } finally {
558:                                    m_resolver.release(includedSource);
559:                                }
560:                            } else {
561:                                isValid = (valid == 1);
562:                            }
563:                            if (!isValid) {
564:                                m_store.remove(key);
565:                                return null;
566:                            }
567:                        }
568:                        storedValidity = aggregated;
569:                    }
570:                }
571:
572:                TransformerHandler handler = m_factory
573:                        .newTransformerHandler((Templates) templateAndValidityAndIncludes[0]);
574:                handler.getTransformer()
575:                        .setErrorListener(
576:                                new TraxErrorListener(getLogger(), stylesheet
577:                                        .getURI()));
578:                handler.getTransformer().setURIResolver(this );
579:                return new MyTransformerHandlerAndValidity(handler,
580:                        storedValidity);
581:            }
582:
583:            private void putTemplates(Templates templates, Source stylesheet,
584:                    String id) throws IOException {
585:                if (!m_useStore)
586:                    return;
587:
588:                // we must augment the template ID with the factory classname since one
589:                // transformer implementation cannot handle the instances of a
590:                // template created by another one.
591:                String key = "XSLTTemplate: " + id + '('
592:                        + m_factory.getClass().getName() + ')';
593:
594:                // only stylesheets with a last modification date are stored
595:                SourceValidity validity = stylesheet.getValidity();
596:                if (null != validity) {
597:                    // Stored is an array of the template and the current time
598:                    Object[] templateAndValidityAndIncludes = new Object[3];
599:                    templateAndValidityAndIncludes[0] = templates;
600:                    templateAndValidityAndIncludes[1] = validity;
601:                    if (m_checkIncludes) {
602:                        templateAndValidityAndIncludes[2] = m_includesMap
603:                                .get(id);
604:                    }
605:                    m_store.store(key, templateAndValidityAndIncludes);
606:                }
607:            }
608:
609:            /**
610:             * Called by the processor when it encounters an xsl:include, xsl:import, or
611:             * document() function.
612:             * 
613:             * @param href
614:             *            An href attribute, which may be relative or absolute.
615:             * @param base
616:             *            The base URI in effect when the href attribute was
617:             *            encountered.
618:             * 
619:             * @return A Source object, or null if the href cannot be resolved, and the
620:             *         processor should try to resolve the URI itself.
621:             * 
622:             * @throws TransformerException
623:             *             if an error occurs when trying to resolve the URI.
624:             */
625:            public javax.xml.transform.Source resolve(String href, String base)
626:                    throws TransformerException {
627:                if (getLogger().isDebugEnabled()) {
628:                    getLogger().debug(
629:                            "resolve(href = " + href + ", base = " + base
630:                                    + "); resolver = " + m_resolver);
631:                }
632:
633:                Source xslSource = null;
634:                try {
635:                    if (base == null || href.indexOf(":") > 1) {
636:                        // Null base - href must be an absolute URL
637:                        xslSource = m_resolver.resolveURI(href);
638:                    } else if (href.length() == 0) {
639:                        // Empty href resolves to base
640:                        xslSource = m_resolver.resolveURI(base);
641:                    } else {
642:                        // is the base a file or a real m_url
643:                        if (!base.startsWith("file:")) {
644:                            int lastPathElementPos = base.lastIndexOf('/');
645:                            if (lastPathElementPos == -1) {
646:                                // this should never occur as the base should
647:                                // always be protocol:/....
648:                                return null; // we can't resolve this
649:                            } else {
650:                                xslSource = m_resolver.resolveURI(base
651:                                        .substring(0, lastPathElementPos)
652:                                        + "/" + href);
653:                            }
654:                        } else {
655:                            File parent = new File(base.substring(5));
656:                            File parent2 = new File(parent.getParentFile(),
657:                                    href);
658:                            xslSource = m_resolver.resolveURI(parent2.toURL()
659:                                    .toExternalForm());
660:                        }
661:                    }
662:
663:                    InputSource is = getInputSource(xslSource);
664:
665:                    if (getLogger().isDebugEnabled()) {
666:                        getLogger().debug(
667:                                "xslSource = " + xslSource + ", system id = "
668:                                        + xslSource.getURI());
669:                    }
670:
671:                    if (m_checkIncludes) {
672:                        // Populate included validities
673:                        List includes = (List) m_includesMap.get(base);
674:                        if (includes != null) {
675:                            SourceValidity included = xslSource.getValidity();
676:                            if (included != null) {
677:                                includes.add(new Object[] { xslSource.getURI(),
678:                                        xslSource.getValidity() });
679:                            } else {
680:                                // One of the included stylesheets is not cacheable
681:                                m_includesMap.remove(base);
682:                            }
683:                        }
684:                    }
685:
686:                    return new StreamSource(is.getByteStream(), is
687:                            .getSystemId());
688:                } catch (SourceException e) {
689:                    if (getLogger().isDebugEnabled()) {
690:                        getLogger().debug(
691:                                "Failed to resolve " + href + "(base = " + base
692:                                        + "), return null", e);
693:                    }
694:
695:                    // CZ: To obtain the same behaviour as when the resource is
696:                    // transformed by the XSLT Transformer we should return null here.
697:                    return null;
698:                } catch (java.net.MalformedURLException mue) {
699:                    if (getLogger().isDebugEnabled()) {
700:                        getLogger().debug(
701:                                "Failed to resolve " + href + "(base = " + base
702:                                        + "), return null", mue);
703:                    }
704:
705:                    return null;
706:                } catch (IOException ioe) {
707:                    if (getLogger().isDebugEnabled()) {
708:                        getLogger().debug(
709:                                "Failed to resolve " + href + "(base = " + base
710:                                        + "), return null", ioe);
711:                    }
712:
713:                    return null;
714:                } finally {
715:                    m_resolver.release(xslSource);
716:                }
717:            }
718:
719:            /**
720:             * Return a new <code>InputSource</code> object that uses the
721:             * <code>InputStream</code> and the system ID of the <code>Source</code>
722:             * object.
723:             * 
724:             * @throws IOException
725:             *             if I/O error occured.
726:             */
727:            protected InputSource getInputSource(final Source source)
728:                    throws IOException, SourceException {
729:                final InputSource newObject = new InputSource(source
730:                        .getInputStream());
731:                newObject.setSystemId(source.getURI());
732:                return newObject;
733:            }
734:
735:            /**
736:             * Recycle the component
737:             */
738:            public void recycle() {
739:                m_includesMap.clear();
740:                // restore default factory
741:                if (m_factory != m_defaultFactory) {
742:                    m_factory = m_defaultFactory;
743:                }
744:            }
745:
746:            /**
747:             * Subclass to allow for instanciation, as for some unknown reason the
748:             * constructor is protected....
749:             */
750:            public static class MyTransformerHandlerAndValidity extends
751:                    TransformerHandlerAndValidity {
752:
753:                protected MyTransformerHandlerAndValidity(
754:                        TransformerHandler handler, SourceValidity validity) {
755:                    super(handler, validity);
756:                }
757:            }
758:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.