View Javadoc

1   /*******************************************************************************
2    * Copyright (c) 2007, 2014 Massimiliano Ziccardi
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 it.jnrpe.server.plugins;
17  
18  import it.jnrpe.plugins.PluginConfigurationException;
19  import it.jnrpe.plugins.PluginRepository;
20  import it.jnrpe.utils.PluginRepositoryUtil;
21  import it.jnrpe.utils.StreamManager;
22  
23  import java.io.File;
24  import java.io.FilenameFilter;
25  import java.io.InputStream;
26  import java.net.MalformedURLException;
27  import java.net.URL;
28  import java.util.ArrayList;
29  import java.util.List;
30  import java.util.jar.JarEntry;
31  import java.util.jar.JarFile;
32  
33  import org.slf4j.Logger;
34  import org.slf4j.LoggerFactory;
35  
36  /**
37   * This object represent a Plugin repository loaded dynamically from file
38   * system.
39   * 
40   * @author Massimiliano Ziccardi
41   * 
42   */
43  public class DynaPluginRepository extends PluginRepository {
44  
45  	/**
46  	 * The logger.
47  	 */
48  	private static final Logger LOG = LoggerFactory
49  			.getLogger(DynaPluginRepository.class);
50  
51  	/**
52  	 * Filter for jar files.
53  	 */
54  	private static final JarFilefilter JAR_FILE_FILTER = new JarFilefilter();
55  
56  	/**
57  	 * File filter class for jar files.
58  	 * 
59  	 * @author Massimiliano Ziccardi
60  	 */
61  	private static class JarFilefilter implements FilenameFilter {
62  		/**
63  		 * Returns <code>true</code> if the file name ends with ".jar".
64  		 * 
65  		 * @param dir
66  		 *            The directory containing the file
67  		 * @param name
68  		 *            The filename
69  		 * @return <code>true</code> if the file name ends with ".jar".
70  		 */
71  		public boolean accept(final File dir, final String name) {
72  			return name.endsWith(".jar");
73  		}
74  	}
75  
76  	/**
77  	 * Loads all the plugins definitions from the given directory.
78  	 * 
79  	 * @param fDir
80  	 *            The plugin package directory.
81  	 * @throws PluginConfigurationException
82  	 *             -
83  	 */
84  	private void configurePlugins(final File fDir)
85  			throws PluginConfigurationException {
86  		LOG.trace("READING PLUGIN CONFIGURATION FROM DIRECTORY "
87  				+ fDir.getName());
88  		StreamManager streamMgr = new StreamManager();
89  
90  		File[] vfJars = fDir.listFiles(JAR_FILE_FILTER);
91  
92  		if (vfJars == null || vfJars.length == 0) {
93  			return;
94  		}
95  
96  		// Initializing classloader
97  		List<URL> vUrls = new ArrayList<URL>(vfJars.length);
98  
99  		ClassLoader ul = null;
100 
101 		for (int j = 0; j < vfJars.length; j++) {
102 			try {
103 				vUrls.add(vfJars[j].toURI().toURL());
104 			} catch (MalformedURLException e) {
105 				// should never happen
106 				throw new IllegalStateException(e);
107 			}
108 		}
109 
110 		ul = new JNRPEClassLoader(vUrls);
111 
112 		try {
113 			for (File file : vfJars) {
114 				JarFile jarFile = null;
115 				try {
116 					jarFile = new JarFile(file);
117 					JarEntry entry = jarFile.getJarEntry("plugin.xml");
118 					if (entry == null) {
119 						entry = jarFile.getJarEntry("jnrpe_plugins.xml");
120 					}
121 
122 					if (entry == null) {
123 						// The jar do not contain a jnrpe_plugins.xml nor a
124 						// plugin.xml file...
125 						continue;
126 					}
127 
128 					InputStream in = streamMgr.handle(jarFile
129 							.getInputStream(entry));
130 					PluginRepositoryUtil.loadFromXmlPluginPackageDefinitions(
131 							this, ul, in);
132 					in.close();
133 
134 				} catch (Exception e) {
135 					LOG.error("Skipping plugin package contained in file '"
136 							+ file.getName()
137 							+ "' because of the following error : {}",
138 							new String[] { e.getMessage() }, e);
139 				} finally {
140 					try {
141 						jarFile.close();
142 					} catch (Exception e) {
143 						// Intentionally ignored...
144 					}
145 				}
146 			}
147 
148 		} finally {
149 			streamMgr.closeAll();
150 		}
151 	}
152 
153 	/**
154 	 * Loops through all the directories present inside the JNRPE plugin
155 	 * directory.
156 	 * 
157 	 * @param fDirectory
158 	 *            The JNRPE plugins directory
159 	 * @throws PluginConfigurationException
160 	 *             -
161 	 */
162 	public final void load(final File fDirectory)
163 			throws PluginConfigurationException {
164 		File[] vFiles = fDirectory.listFiles();
165 		if (vFiles != null) {
166 			for (File f : vFiles) {
167 				if (f.isDirectory()) {
168 					configurePlugins(f);
169 				}
170 			}
171 		}
172 	}
173 }