001 /* 002 * Copyright (C) 2012 eXo Platform SAS. 003 * 004 * This is free software; you can redistribute it and/or modify it 005 * under the terms of the GNU Lesser General Public License as 006 * published by the Free Software Foundation; either version 2.1 of 007 * the License, or (at your option) any later version. 008 * 009 * This software is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * You should have received a copy of the GNU Lesser General Public 015 * License along with this software; if not, write to the Free 016 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 017 * 02110-1301 USA, or see the FSF site: http://www.fsf.org. 018 */ 019 020 package org.crsh.standalone; 021 022 import org.crsh.plugin.PluginContext; 023 import org.crsh.plugin.PluginLifeCycle; 024 import org.crsh.plugin.ServiceLoaderDiscovery; 025 import org.crsh.vfs.FS; 026 import org.crsh.vfs.Path; 027 import org.crsh.vfs.spi.FSDriver; 028 029 import java.io.File; 030 import java.io.IOException; 031 import java.net.URISyntaxException; 032 import java.net.URL; 033 import java.net.URLClassLoader; 034 import java.util.Collections; 035 import java.util.Map; 036 import java.util.logging.Logger; 037 038 /** 039 * A boostrap for starting a standalone CRaSH. 040 */ 041 public class Bootstrap extends PluginLifeCycle { 042 043 /** . */ 044 protected final Logger log = Logger.getLogger(getClass().getName()); 045 046 /** The configuration file system. */ 047 private final FS confFS; 048 049 /** The command file system. */ 050 private final FS cmdFS; 051 052 /** The base classloader. */ 053 private final ClassLoader loader; 054 055 /** The attributes. */ 056 private Map<String, Object> attributes; 057 058 /** 059 * Create a bootstrap instance with the base classloader and an empty and unmodifiable attribute map. 060 * 061 * @param baseLoader the base classloader crash will use 062 * @param confFS the conf file system 063 * @param cmdFS the cmd file system 064 * @throws NullPointerException if any argument is null 065 */ 066 public Bootstrap(ClassLoader baseLoader, FS confFS, FS cmdFS) throws NullPointerException { 067 if (baseLoader == null) { 068 throw new NullPointerException("No null base loader accepted"); 069 } 070 if (confFS == null) { 071 throw new NullPointerException("No null conf file system accepted"); 072 } 073 if (cmdFS == null) { 074 throw new NullPointerException("No null cmd file system accepted"); 075 } 076 this.attributes = Collections.emptyMap(); 077 this.confFS = confFS; 078 this.cmdFS = cmdFS; 079 this.loader = new URLClassLoader(new URL[]{}, baseLoader); 080 } 081 082 /** 083 * Create a bootstrap instance with the base classloader and an empty and unmodifiable attribute map. 084 * 085 * @param baseLoader the base classloader crash will use 086 * @throws NullPointerException if any argument is null 087 */ 088 public Bootstrap(ClassLoader baseLoader) throws NullPointerException { 089 this(baseLoader, new FS(), new FS()); 090 } 091 092 /** 093 * Replaces the attributes to use, the new attributes map will be used as is and not copied. 094 * 095 * @param attributes the attribute map 096 */ 097 public void setAttributes(Map<String, Object> attributes) { 098 this.attributes = attributes; 099 } 100 101 /** 102 * Add a configuration path driver. 103 * 104 * @param driver the configuration driver 105 * @return this bootstrap 106 * @throws NullPointerException when the driver is null 107 * @throws IOException any io exception 108 */ 109 public Bootstrap addToConfPath(FSDriver<?> driver) throws IOException, NullPointerException { 110 if (driver == null) { 111 throw new NullPointerException("No null conf driver"); 112 } 113 log.info("Added " + driver + " driver to conf path"); 114 confFS.mount(driver); 115 return this; 116 } 117 118 /** 119 * Add a configuration path directory. 120 * 121 * @param path the configuration path 122 * @return this bootstrap 123 * @throws NullPointerException when the path argument is null 124 * @throws IOException any io exception 125 */ 126 public Bootstrap addToConfPath(File path) throws NullPointerException, IOException { 127 if (path == null) { 128 throw new NullPointerException("No null conf path"); 129 } 130 log.info("Added " + path.getCanonicalPath() + " file to conf path"); 131 confFS.mount(path); 132 return this; 133 } 134 135 /** 136 * Add a configuration path. 137 * 138 * @param path the configuration path 139 * @return this bootstrap 140 * @throws NullPointerException when the path argument is null 141 * @throws IOException any io exception 142 * @throws URISyntaxException any uri syntax exception 143 */ 144 public Bootstrap addToConfPath(Path path) throws NullPointerException, IOException, URISyntaxException { 145 if (path == null) { 146 throw new NullPointerException("No null conf path"); 147 } 148 log.info("Added " + path.getValue() + " path to conf path"); 149 confFS.mount(loader, path); 150 return this; 151 } 152 153 /** 154 * Add a command path driver. 155 * 156 * @param driver the command driver 157 * @return this bootstrap 158 * @throws NullPointerException when the driver is null 159 * @throws IOException any io exception 160 */ 161 public Bootstrap addToCmdPath(FSDriver<?> driver) throws IOException, NullPointerException { 162 if (driver == null) { 163 throw new NullPointerException("No null conf driver"); 164 } 165 log.info("Added " + driver + " driver to command path"); 166 cmdFS.mount(driver); 167 return this; 168 } 169 170 /** 171 * Add a command path directory. 172 * 173 * @param path the command path 174 * @return this bootstrap 175 * @throws NullPointerException when the path argument is null 176 * @throws IOException any io exception 177 */ 178 public Bootstrap addToCmdPath(File path) throws NullPointerException, IOException { 179 if (path == null) { 180 throw new NullPointerException("No null command path"); 181 } 182 log.info("Added " + path.getAbsolutePath() + " file to command path"); 183 cmdFS.mount(path); 184 return this; 185 } 186 187 /** 188 * Add a command path directory. 189 * 190 * @param path the command path 191 * @return this bootstrap 192 * @throws NullPointerException when the path argument is null 193 * @throws IOException any io exception 194 * @throws URISyntaxException any uri syntax exception 195 */ 196 public Bootstrap addToCmdPath(Path path) throws NullPointerException, IOException, URISyntaxException { 197 if (path == null) { 198 throw new NullPointerException("No null command path"); 199 } 200 log.info("Added " + path.getValue() + " path to command path"); 201 cmdFS.mount(loader, path); 202 return this; 203 } 204 205 /** 206 * Trigger the boostrap. 207 * 208 * @throws Exception any exception that would prevent the bootstrap 209 */ 210 public void bootstrap() throws Exception { 211 212 // The service loader discovery 213 ServiceLoaderDiscovery discovery = new ServiceLoaderDiscovery(loader); 214 215 // 216 PluginContext context = new PluginContext( 217 discovery, 218 attributes, 219 cmdFS, 220 confFS, 221 loader); 222 223 // 224 context.refresh(); 225 226 // 227 start(context); 228 } 229 230 public void shutdown() { 231 stop(); 232 } 233 }