Index: test/java/org/apache/xmlgraphics/StandardTestSuite.java =================================================================== --- test/java/org/apache/xmlgraphics/StandardTestSuite.java (revision 559827) +++ test/java/org/apache/xmlgraphics/StandardTestSuite.java (working copy) @@ -23,6 +23,7 @@ import org.apache.xmlgraphics.ps.PSEscapeTestCase; import org.apache.xmlgraphics.ps.dsc.events.DSCValueParserTestCase; import org.apache.xmlgraphics.ps.dsc.tools.DSCToolsTestCase; +import org.apache.xmlgraphics.util.ClasspathResourceTest; import org.apache.xmlgraphics.util.ServiceTest; import org.apache.xmlgraphics.util.io.ASCII85InputStreamTestCase; import org.apache.xmlgraphics.util.io.ASCII85OutputStreamTestCase; @@ -49,6 +50,7 @@ suite.addTest(new TestSuite(ASCII85OutputStreamTestCase.class)); suite.addTest(new TestSuite(PNGEncoderTest.class)); suite.addTest(new TestSuite(ServiceTest.class)); + suite.addTest(new TestSuite(ClasspathResourceTest.class)); suite.addTest(new TestSuite(PSEscapeTestCase.class)); suite.addTest(new TestSuite(DSCValueParserTestCase.class)); suite.addTest(new TestSuite(DSCToolsTestCase.class)); Index: test/java/org/apache/xmlgraphics/util/ClasspathResourceTest.java =================================================================== --- test/java/org/apache/xmlgraphics/util/ClasspathResourceTest.java (revision 0) +++ test/java/org/apache/xmlgraphics/util/ClasspathResourceTest.java (revision 0) @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id: $ */ + +package org.apache.xmlgraphics.util; + +import java.net.URL; +import java.util.Iterator; +import java.util.List; + +import junit.framework.TestCase; + +/** + * Test for the Service class. + */ +public class ClasspathResourceTest extends TestCase { + + /** + * Tests whether the file /sample.txt with mime-type text/plain exists. + * + * @throws Exception + * in case of an error + */ + public void testSampleResource() throws Exception { + final List list = ClasspathResource.getClassPathResource() + .listResourcesOfMimeType("text/plain"); + boolean found = false; + final Iterator i = list.iterator(); + while (i.hasNext()) { + final URL u = (URL) i.next(); + if (u.getPath().endsWith("sample.txt")) { + found = true; + } + } + assertTrue(found); + } + + /** + * Tests the mode where Service returns class names. + * + * @throws Exception + * in case of an error + */ + public void testNonexistingResource() throws Exception { + final List list = ClasspathResource.getClassPathResource() + .listResourcesOfMimeType("nota/mime-type"); + assertTrue(list.isEmpty()); + } + +} Index: test/resources/sample.txt =================================================================== --- test/resources/sample.txt (revision 0) +++ test/resources/sample.txt (revision 0) @@ -0,0 +1 @@ +A sample text Index: test/resources/META-INF/MANIFEST.MF =================================================================== --- test/resources/META-INF/MANIFEST.MF (revision 0) +++ test/resources/META-INF/MANIFEST.MF (revision 0) @@ -0,0 +1,4 @@ +Manifest-Version: 1.0 + +Name: sample.txt +Content-Type: text/plain Index: src/java/org/apache/xmlgraphics/util/ClasspathResource.java =================================================================== --- src/java/org/apache/xmlgraphics/util/ClasspathResource.java (revision 0) +++ src/java/org/apache/xmlgraphics/util/ClasspathResource.java (revision 0) @@ -0,0 +1,141 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id: Service.java 496556 2007-01-16 00:59:48Z cam $ */ + +package org.apache.xmlgraphics.util; + +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Vector; +import java.util.jar.Attributes; +import java.util.jar.Manifest; + +/** + * A class to find resources in the classpath by their mime-type specified in + * the MANIFEST. + *

+ * This class searches for content entries in all META-INF/MANIFEST.MF files. It + * will find files with a given Content-Type: attribute. This allows to add + * arbitrary resources by content-type just by creating a JAR wrapper and adding + * them to the classpath. + *

+ * Example:
+ * + *

+ * Name: test.txt
+ * Content-Type: text/plain
+ * 
+ */ +public final class ClasspathResource { + + /** + * Actual Type: Map<String,List<URL>>. + */ + private final Map contentMappings; + + private static final String MANIFEST_PATH = "META-INF/MANIFEST.MF"; + + private static final String CONTENT_TYPE_KEY = "Content-Type"; + + private static ClasspathResource classpathResource; + + private ClasspathResource() { + contentMappings = new HashMap(); + loadManifests(); + } + + /** + * Retrieve the singleton instance of this class. + * + * @return the ClassPathResource instance. + */ + public static synchronized ClasspathResource getClassPathResource() { + if (classpathResource == null) { + classpathResource = new ClasspathResource(); + } + return classpathResource; + } + + private void loadManifests() { + Enumeration e; + try { + e = ClassLoader.getSystemClassLoader().getResources(MANIFEST_PATH); + + while (e.hasMoreElements()) { + final URL u = (URL) e.nextElement(); + try { + final Manifest manifest = new Manifest(u.openStream()); + final Map entries = manifest.getEntries(); + final Iterator entrysetiterator = entries.entrySet() + .iterator(); + while (entrysetiterator.hasNext()) { + final Map.Entry entry = (Map.Entry) entrysetiterator + .next(); + final String name = (String) entry.getKey(); + final Attributes attributes = (Attributes) entry + .getValue(); + final String contentType = attributes + .getValue(CONTENT_TYPE_KEY); + if (contentType != null) { + addToMapping(contentType, name); + } + } + } catch (IOException io) { + // TODO: Log. + } + } + } catch (IOException io) { + // TODO: Log. + } + } + + private void addToMapping(final String contentType, final String name) { + List existingFiles = (List) contentMappings.get(contentType); + if (existingFiles == null) { + existingFiles = new Vector(); + contentMappings.put(contentType, existingFiles); + } + final URL url = ClassLoader.getSystemClassLoader().getResource(name); + if (url != null) { + existingFiles.add(url); + } + } + + /** + * Retrieve a list of resources known to have the given mime-type. + * + * @param mimeType + * the mime-type to search for. + * @return a List<URL>, guaranteed to be != null. + */ + public List listResourcesOfMimeType(final String mimeType) { + final List content = (List) contentMappings.get(mimeType); + if (content == null) { + return new ArrayList(0); + } else { + return content; + } + } + +} Index: build.xml =================================================================== --- build.xml (revision 559827) +++ build.xml (working copy) @@ -321,6 +321,9 @@ + + +