1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.log4j.chainsaw.help;
19
20 import org.apache.log4j.LogManager;
21 import org.apache.log4j.Logger;
22 import org.apache.log4j.chainsaw.messages.MessageCenter;
23
24 import java.net.MalformedURLException;
25 import java.net.URL;
26 import java.net.URLClassLoader;
27 import java.util.ArrayList;
28 import java.util.Arrays;
29 import java.util.List;
30
31 /**
32 * A helper class that assists the HelpManager by serving as a collection of
33 * Class loaders based on URL roots.
34 *
35 * @author Paul Smith
36 * <psmith@apache.org>
37 */
38 class HelpLocator {
39 private List<ClassLoader> classLoaders = new ArrayList<>();
40 private static Logger logger = LogManager.getLogger(HelpLocator.class);
41
42 HelpLocator() {
43 }
44
45 /**
46 * Adds a ClassLoader to be used as a help resource locator
47 */
48 void installClassloaderLocator(ClassLoader cl) {
49 classLoaders.add(cl);
50 }
51
52 /**
53 * Adds a new locator to the current set of locators by using the passed in
54 * URL as a base to locate help resources. The URL SHOULD end in a '/'
55 * character.
56 */
57 void installLocator(URL url) {
58 try {
59 classLoaders.add(new HelpResourceLoader(url));
60 } catch (Exception e) {
61 MessageCenter.getInstance().getLogger().error(
62 "Failed to setup the resoure loaders for the Help Subsystem");
63 }
64 }
65
66 /**
67 * Locates a help resource by using the internal resource locator collection.
68 *
69 * @return URL of the located resource, or null if it cannot be located.
70 */
71 URL findResource(String name) {
72 URL url = null;
73
74 for (Object classLoader : classLoaders) {
75 ClassLoader loader = (ClassLoader) classLoader;
76 url = loader.getResource(name);
77
78 if (url != null) {
79 break;
80 }
81 }
82
83 return url;
84 }
85
86 private static class HelpResourceLoader extends ClassLoader {
87 private URL root;
88
89 private HelpResourceLoader(URL root) {
90 this.root = root;
91 }
92
93 /*
94 * (non-Javadoc)
95 *
96 * @see java.lang.ClassLoader#findResource(java.lang.String)
97 */
98 protected URL findResource(String name) {
99 URL url = super.findResource(name);
100
101 if (url != null) {
102 return url;
103 }
104
105 try {
106 URL resourceURL = new URL(root, name);
107 URL[] urlArray = new URL[]{root, resourceURL};
108 logger.debug("Looking for Help resource at:" + resourceURL.toExternalForm());
109 logger.debug("urlArray=" + Arrays.asList(urlArray));
110 return new URLClassLoader(
111 urlArray).findResource(
112 name);
113 } catch (MalformedURLException e) {
114 e.printStackTrace();
115 }
116
117 return null;
118 }
119 }
120
121 // public static void main(String[] args) throws Exception {
122 // HelpLocator locator = new HelpLocator();
123 // locator.installLocator(new File(".").toURL());
124 // locator.installLocator(new
125 // URL("http://java.sun.com/j2se/1.4.2/docs/api/"));
126 // String[] resources =
127 // new String[] { "build.properties", "java/lang/ClassLoader.html", };
128 //
129 // for (int i = 0; i < resources.length; i++) {
130 // String resource = resources[i];
131 // URL url = locator.findResource(resource);
132 // System.out.println("resource=" + resource + ", url=" + url);
133 // }
134 // }
135 }