CharacterSetType charsetType, AFPResourceAccessor accessor, AFPEventProducer eventProducer)
throws IOException {
// check for cached version of the characterset
- String descriptor = characterSetName + "_" + encoding + "_" + codePageName;
- CharacterSet characterSet = (CharacterSet) characterSetsCache.get(descriptor);
-
+ URI charSetURI = accessor.resolveURI(characterSetName);
+ String cacheKey = charSetURI.toASCIIString() + "_" + characterSetName + "_" + codePageName;
+ CharacterSet characterSet = (CharacterSet) characterSetsCache.get(cacheKey);
if (characterSet != null) {
return characterSet;
}
* chracter global identifier.
*/
Map<String, String> codePage;
+ // TODO: This could have performance implications if several threads want to use the
+ // codePagesCache to retrieve different codepages.
synchronized (codePagesCache) {
codePage = codePagesCache.get(codePageName);
} finally {
closeInputStream(inputStream);
}
- characterSetsCache.put(descriptor, characterSet);
+ characterSetsCache.put(cacheKey, characterSet);
return characterSet;
}
import java.net.URI;
import java.net.URISyntaxException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
import org.apache.fop.apps.io.InternalResourceResolver;
/**
*/
public final class AFPResourceAccessor {
+ private static final Log log = LogFactory.getLog(AFPResourceAccessor.class);
+
private final InternalResourceResolver resourceResolver;
- private final String baseURI;
+ private final URI baseURI;
+ private final URIResolver uriResolver;
/**
* Constructor for resource to be accessed via the {@link org.apache.fop.apps.FOUserAgent}. This
*/
public AFPResourceAccessor(InternalResourceResolver resourceResolver, String baseURI) {
this.resourceResolver = resourceResolver;
- this.baseURI = baseURI;
+ URI actualBaseURI = null;
+ URIResolver uriResolver;
+ if (baseURI == null) {
+ actualBaseURI = null;
+ uriResolver = new NullBaseURIResolver();
+ } else {
+ try {
+ actualBaseURI = InternalResourceResolver.getBaseURI(baseURI);
+ uriResolver = new BaseURIResolver();
+ } catch (URISyntaxException use) {
+ log.error("The URI given \"" + baseURI + "\" is invalid: " + use.getMessage());
+ actualBaseURI = null;
+ uriResolver = new NullBaseURIResolver();
+ }
+ }
+ this.baseURI = actualBaseURI;
+ this.uriResolver = uriResolver;
}
/**
this(resourceResolver, null);
}
- private URI getResourceURI(URI uri) {
- if (baseURI == null) {
- return uri;
- }
- try {
- URI baseURI = InternalResourceResolver.getBaseURI(this.baseURI);
- return baseURI.resolve(uri);
- } catch (URISyntaxException use) {
- return uri;
- }
- }
-
/**
* Creates an {@link InputStream} given a URI.
*
* @throws IOException if an I/O error occurs while creating the InputStream.
*/
public InputStream createInputStream(URI uri) throws IOException {
- return resourceResolver.getResource(getResourceURI(uri));
+ return resourceResolver.getResource(uriResolver.resolveURI(uri));
+ }
+
+ /**
+ * Returns the resolved URI, given the URI of a resource.
+ *
+ * @param uri the resource URI
+ * @return the resolved URI
+ */
+ public URI resolveURI(String uri) {
+ return uriResolver.resolveURI(uri);
+ }
+
+ private interface URIResolver {
+ URI resolveURI(URI uri);
+
+ URI resolveURI(String uri);
+ }
+
+ private final class NullBaseURIResolver implements URIResolver {
+
+ public URI resolveURI(URI uri) {
+ return uri;
+ }
+
+ public URI resolveURI(String uri) {
+ return URI.create("./" + uri.trim());
+ }
+ }
+
+ private final class BaseURIResolver implements URIResolver {
+
+ public URI resolveURI(URI uri) {
+ return baseURI.resolve(uri);
+ }
+
+ public URI resolveURI(String uri) {
+ return baseURI.resolve(uri.trim());
+ }
}
}