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.resolver;
018:
019: import org.apache.excalibur.xml.EntityResolver;
020: import org.apache.avalon.framework.activity.Disposable;
021: import org.apache.avalon.framework.component.ComponentException;
022: import org.apache.avalon.framework.component.ComponentManager;
023: import org.apache.avalon.framework.component.Composable;
024: import org.apache.avalon.framework.context.Context;
025: import org.apache.avalon.framework.context.ContextException;
026: import org.apache.avalon.framework.context.Contextualizable;
027: import org.apache.avalon.framework.logger.AbstractLogEnabled;
028: import org.apache.avalon.framework.parameters.ParameterException;
029: import org.apache.avalon.framework.parameters.Parameterizable;
030: import org.apache.avalon.framework.parameters.Parameters;
031: import org.apache.avalon.framework.thread.ThreadSafe;
032: import org.apache.cocoon.Constants;
033: import org.apache.xml.resolver.CatalogManager;
034: import org.apache.xml.resolver.tools.CatalogResolver;
035: import org.xml.sax.InputSource;
036: import org.xml.sax.SAXException;
037:
038: import java.io.IOException;
039:
040: /**
041: * A component that uses catalogs for resolving entities.
042: * This implementation uses the XML Entity and URI Resolvers from
043: * http://xml.apache.org/commons/
044: * published by Norman Walsh. More information on the catalogs can be
045: * found at
046: * http://cocoon.apache.org/userdocs/concepts/catalog.html
047: *
048: * The catalog is by default loaded from "WEB-INF/entities/catalog".
049: * This can be configured by the "catalog" parameter in the cocoon.xconf:
050: * <entity-resolver>
051: * <parameter name="catalog" value="mycatalog"/>
052: * </entity-resolver>
053: *
054: * @author <a href="mailto:dims@yahoo.com">Davanum Srinivas</a>
055: * @author <a href="mailto:crossley@apache.org">David Crossley</a>
056: * @version CVS $Id: ResolverImpl.java 433543 2006-08-22 06:22:54Z crossley $
057: * @since 2.0rc1
058: */
059: public class ResolverImpl extends AbstractLogEnabled implements
060: EntityResolver, Resolver, Contextualizable, Composable,
061: Parameterizable, ThreadSafe, Disposable {
062:
063: /** The catalog manager */
064: protected CatalogManager catalogManager = new CatalogManager();
065:
066: /** The catalog resolver */
067: protected CatalogResolver catalogResolver = new CatalogResolver(
068: catalogManager);
069:
070: /** The component manager */
071: protected ComponentManager manager = null;
072:
073: /** The context */
074: protected org.apache.cocoon.environment.Context context;
075:
076: /** Contextualize this class */
077: public void contextualize(Context context) throws ContextException {
078: this .context = (org.apache.cocoon.environment.Context) context
079: .get(Constants.CONTEXT_ENVIRONMENT_CONTEXT);
080: }
081:
082: /**
083: * Set the configuration. Load the system catalog and apply any
084: * parameters that may have been specified in cocoon.xconf
085: * @param params The configuration information
086: * @exception ParameterException
087: */
088: public void parameterize(Parameters params)
089: throws ParameterException {
090:
091: /* Over-ride debug level that is set by CatalogManager.properties */
092: String verbosity = params.getParameter("verbosity", "");
093: if (verbosity != "") {
094: if (this .getLogger().isDebugEnabled()) {
095: this .getLogger().debug(
096: "Setting Catalog resolver "
097: + "verbosity level to " + verbosity);
098: }
099: int verbosityLevel = 0;
100: try {
101: verbosityLevel = Integer.parseInt(verbosity);
102: catalogManager.setVerbosity(verbosityLevel);
103: } catch (NumberFormatException ce1) {
104: this .getLogger().warn(
105: "Trouble setting Catalog verbosity", ce1);
106: }
107: }
108:
109: /* Load the built-in catalog */
110: String catalogFile = params.getParameter("catalog",
111: "/WEB-INF/entities/catalog");
112: try {
113: String catalogURL = null;
114: catalogURL = this .context.getRealPath(catalogFile);
115: if (catalogURL == null) {
116: catalogURL = this .context.getResource(catalogFile)
117: .toExternalForm();
118: }
119: if (this .getLogger().isDebugEnabled()) {
120: this .getLogger().debug(
121: "System OASIS Catalog URL is " + catalogURL);
122: }
123: catalogResolver.getCatalog().parseCatalog(catalogURL);
124: } catch (Exception e) {
125: this .getLogger().warn("Could not get Catalog URL", e);
126: }
127:
128: /* Load a single additional local catalog */
129: String localCatalogFile = params.getParameter("local-catalog",
130: null);
131: if (localCatalogFile != null) {
132: try {
133: if (this .getLogger().isDebugEnabled()) {
134: this .getLogger()
135: .debug(
136: "Additional Catalog is "
137: + localCatalogFile);
138: }
139: catalogResolver.getCatalog().parseCatalog(
140: localCatalogFile);
141: } catch (Exception e) {
142: this .getLogger().warn(
143: "Could not get local Catalog file", e);
144: }
145: }
146: }
147:
148: /**
149: * Set the global component manager.
150: * @param manager The global component manager
151: * @exception ComponentException
152: */
153: public void compose(ComponentManager manager)
154: throws ComponentException {
155: if ((this .manager == null) && (manager != null)) {
156: this .manager = manager;
157: }
158: }
159:
160: /**
161: * Allow the application to resolve external entities.
162: *
163: * <p>The Parser will call this method before opening any external
164: * entity except the top-level document entity (including the
165: * external DTD subset, external entities referenced within the
166: * DTD, and external entities referenced within the document
167: * element): the application may request that the parser resolve
168: * the entity itself, that it use an alternative URI, or that it
169: * use an entirely different input source.</p>
170: *
171: * <p>Application writers can use this method to redirect external
172: * system identifiers to secure and/or local URIs, to look up
173: * public identifiers in a catalogue, or to read an entity from a
174: * database or other input source (including, for example, a dialog
175: * box).</p>
176: *
177: * <p>If the system identifier is a URL, the SAX parser must
178: * resolve it fully before reporting it to the application.</p>
179: *
180: * @param publicId The public identifier of the external entity
181: * being referenced, or null if none was supplied.
182: * @param systemId The system identifier of the external entity
183: * being referenced.
184: * @return An InputSource object describing the new input source,
185: * or null to request that the parser open a regular
186: * URI connection to the system identifier.
187: * @exception org.xml.sax.SAXException Any SAX exception, possibly
188: * wrapping another exception.
189: * @exception java.io.IOException A Java-specific IO exception,
190: * possibly the result of creating a new InputStream
191: * or Reader for the InputSource.
192: * @see org.xml.sax.InputSource
193: */
194: public InputSource resolveEntity(String publicId, String systemId)
195: throws SAXException, IOException {
196: /*
197: if (this.getLogger().isDebugEnabled()) {
198: this.getLogger().debug("CER resolution: publicId="
199: + publicId + " systemId=" + systemId);
200: }
201: */
202: InputSource altInputSource = catalogResolver.resolveEntity(
203: publicId, systemId);
204: if (altInputSource != null) {
205: if (this .getLogger().isDebugEnabled()) {
206: this .getLogger().debug(
207: "Resolved catalog entity: " + publicId + " "
208: + altInputSource.getSystemId());
209: }
210: }
211: /*
212: else {
213: if (this.getLogger().isDebugEnabled()) {
214: this.getLogger().debug("CER: altInputSource is null");
215: }
216: }
217: */
218: return altInputSource;
219: }
220:
221: /**
222: * Dispose
223: */
224: public void dispose() {
225: }
226: }
|