KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > components > validation > impl > CachingValidator


1 /*
2  * Copyright 1999-2005 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.cocoon.components.validation.impl;
17
18 import java.io.IOException JavaDoc;
19
20 import org.apache.cocoon.components.validation.Schema;
21 import org.apache.cocoon.components.validation.SchemaParser;
22 import org.apache.cocoon.components.validation.ValidatorException;
23 import org.apache.excalibur.source.Source;
24 import org.apache.excalibur.source.SourceValidity;
25 import org.apache.excalibur.store.Store;
26 import org.xml.sax.SAXException JavaDoc;
27
28 /**
29  * <p>An extension of the {@link DefaultValidator} class allowing {@link Schema}
30  * instances to be cached.</p>
31  *
32  * <p>The {@link #getSchema(SchemaParser, Source, String)} method will manage
33  * whether to return a cached or a freshly parsed {@link Schema} instance.</p>
34  *
35  * @author <a HREF="mailto:pier@betaversion.org">Pier Fumagalli</a>
36  */

37 public class CachingValidator extends DefaultValidator {
38
39     /** <p>The {@link Store} used for caching {@link Schema}s (if enabled).</p> */
40     private Store store = null;
41
42     /**
43      * <p>Create a new {@link CachingValidator} instance.</p>
44      */

45     public CachingValidator() {
46         super();
47     }
48     
49     /**
50      * <p>Initialize this component instance.</p>
51      */

52     public void initialize()
53     throws Exception JavaDoc {
54         this.store = (Store) this.manager.lookup(Store.TRANSIENT_STORE);
55         super.initialize();
56     }
57     
58     /**
59      * <p>Dispose this component instance.</p>
60      */

61     public void dispose() {
62         try {
63             super.dispose();
64         } finally {
65             if (this.store != null) this.manager.release(this.store);
66         }
67     }
68
69     /**
70      * <p>Return a {@link Schema} instance from the specified {@link SchemaParser}
71      * associated with the given {@link Source} and grammar language.</p>
72      *
73      * <p>This method will overriding the default behaviour specified by the
74      * {@link AbstractValidator#getSchema(SchemaParser, Source, String)} method,
75      * and supports cacheability of {@link Schema} instances through the use of
76      * a {@link Store} looked up using the {@link Store#TRANSIENT_STORE} Avalon
77      * role.</p>
78      *
79      * <p>Cached {@link Schema} instances will be retained in the configured
80      * {@link Store} until the checks on the validity obtained calling the
81      * {@link Schema#getValidity()} method will declare that the schema is still
82      * valid.</p>
83      *
84      * @param parser the {@link SchemaParser} producing the {@link Schema}.
85      * @param source the {@link Source} associated with the {@link Schema} to return.
86      * @param grammar the grammar language of the schema to produce.
87      * @throws SAXException if a grammar error occurred parsing the schema.
88      * @throws IOException if an I/O error occurred parsing the schema.
89      */

90     public Schema getSchema(SchemaParser parser, Source source, String JavaDoc grammar)
91     throws IOException JavaDoc, SAXException JavaDoc {
92
93         /* Prepare a key, and try to get the cached copy of the schema */
94         String JavaDoc uri = source.getURI();
95         String JavaDoc key = this.getClass().getName() + "[" + parser.getClass().getName()
96                      + ":" + grammar + "]@" + source.getURI();
97         Schema schema = null;
98         SourceValidity validity = null;
99         schema = (Schema) this.store.get(key);
100
101         /* If the schema was found verify its validity and optionally clear */
102         if (schema != null) {
103             validity = schema.getValidity();
104             if (validity == null) {
105                 /* Why did we cache it in the first place? */
106                 this.logger.warn("Cached schema " + uri + " has null validity");
107                 this.store.remove(key);
108                 schema = null;
109             } else if (validity.isValid() != SourceValidity.VALID) {
110                 if (this.logger.isDebugEnabled()) {
111                     this.logger.debug("Cached schema " + uri + " no longer valid");
112                 }
113                 this.store.remove(key);
114                 schema = null;
115             } else if (this.logger.isDebugEnabled()) {
116                 this.logger.debug("Valid cached schema found for " + uri);
117             }
118         } else if (this.logger.isDebugEnabled()) {
119             this.logger.debug("Schema " + uri + " not found in cache");
120         }
121
122         /* If the schema was not cached or was cleared, parse and cache it */
123         if (schema == null) {
124             schema = super.getSchema(parser, source, grammar);
125             validity = schema.getValidity();
126             if (validity != null) {
127                 if (validity.isValid() == SourceValidity.VALID) {
128                     this.store.store(key, schema);
129                 }
130             }
131         }
132
133         /* Return the parsed or cached schema */
134         return schema;
135     }
136
137     /**
138      * <p>Attempt to detect the grammar language used by the schema identified
139      * by the specified {@link Source}.</p>
140      *
141      * <p>The grammar languages detected will be cached until the {@link Source}'s
142      * {@link SourceValidity} declares that the schema is valid.</p>
143      *
144      * @param source a {@link Source} instance pointing to the schema to be analyzed.
145      * @throws IOException if an I/O error occurred accessing the schema.
146      * @throws SAXException if an error occurred parsing the schema.
147      * @throws ValidatorException if the language of the schema could not be guessed.
148      */

149     protected String JavaDoc detectGrammar(Source source)
150     throws IOException JavaDoc, SAXException JavaDoc, ValidatorException {
151         /* Prepare a key, and try to get the cached copy of the schema */
152         String JavaDoc uri = source.getURI();
153         String JavaDoc key = this.getClass().getName() + "@" + source.getURI();
154
155         CachedGrammar grammar = null;
156         grammar = (CachedGrammar) this.store.get(key);
157
158         /* If the schema was found verify its validity and optionally clear */
159         if (grammar != null) {
160             if (grammar.validity == null) {
161                 /* Why did we cache it in the first place? */
162                 this.logger.warn("Grammar for " + uri + " has null validity");
163                 this.store.remove(key);
164                 grammar = null;
165             } else if (grammar.validity.isValid() != SourceValidity.VALID) {
166                 if (this.logger.isDebugEnabled()) {
167                     this.logger.debug("Grammar for " + uri + " no longer valid");
168                 }
169                 this.store.remove(key);
170                 grammar = null;
171             } else if (this.logger.isDebugEnabled()) {
172                 this.logger.debug("Valid cached grammar " + grammar + " for " + uri);
173             }
174         }
175
176         /* If the schema was not cached or was cleared, parse and cache it */
177         if (grammar != null) {
178             return grammar.grammar;
179         } else {
180             String JavaDoc language = super.detectGrammar(source);
181             SourceValidity validity = source.getValidity();
182             if (validity != null) {
183                 if (validity.isValid() == SourceValidity.VALID) {
184                     this.store.store(key, new CachedGrammar(validity, language));
185                 }
186             }
187             return language;
188         }
189     }
190     
191     /**
192      * <p>A simple inner class associating grammar languages and source validity
193      * for caching of schema grammar detection.</p>
194      */

195     private static final class CachedGrammar {
196         private final SourceValidity validity;
197         private final String JavaDoc grammar;
198         private CachedGrammar(SourceValidity validity, String JavaDoc grammar) {
199             this.validity = validity;
200             this.grammar = grammar;
201         }
202     }
203 }
204
Popular Tags