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.util.Utils;
026    import org.crsh.vfs.FS;
027    import org.crsh.vfs.Path;
028    
029    import java.io.File;
030    import java.net.URL;
031    import java.net.URLClassLoader;
032    import java.util.Collections;
033    import java.util.List;
034    import java.util.Map;
035    import java.util.logging.Level;
036    import java.util.logging.Logger;
037    
038    public class Bootstrap extends PluginLifeCycle {
039    
040      /** . */
041      protected final Logger log = Logger.getLogger(getClass().getName());
042    
043      /** The mounted path on the file system. */
044      private List<File> cmds = Utils.newArrayList();
045    
046      /** The mounted path on the file system. */
047      private List<File> confs = Utils.newArrayList();
048    
049      /** The class path. */
050      private List<File> jars = Utils.newArrayList();
051    
052      /** The base classloader. */
053      private ClassLoader baseLoader;
054    
055      /** The attributes. */
056      private Map<String, Object> attributes;
057    
058      public Bootstrap(ClassLoader baseLoader) throws NullPointerException {
059        if (baseLoader == null) {
060          throw new NullPointerException("No null base loader accepted");
061        }
062        this.baseLoader = baseLoader;
063        this.attributes = Collections.emptyMap();
064      }
065    
066      public void setAttributes(Map<String, Object> attributes) {
067        this.attributes = attributes;
068      }
069    
070      public Bootstrap addConfPath(File file) {
071        confs.add(file);
072        return this;
073      }
074    
075      public Bootstrap addCmdPath(File file) {
076        cmds.add(file);
077        return this;
078      }
079    
080      public Bootstrap addJarPath(File file) {
081        jars.add(file);
082        return this;
083      }
084    
085      public void bootstrap() throws Exception {
086    
087        // Compute the url classpath
088        URL[] urls = new URL[jars.size()];
089        for (int i = 0;i < urls.length;i++) {
090          urls[i] = jars.get(i).toURI().toURL();
091        }
092    
093        // Create the classloader
094        URLClassLoader classLoader = new URLClassLoader(urls, baseLoader);
095    
096        // Create the cmd file system
097        FS cmdFS = new FS();
098        for (File cmd : cmds) {
099          cmdFS.mount(cmd);
100        }
101    
102        // Add the classloader
103        cmdFS.mount(classLoader, Path.get("/crash/commands/"));
104    
105        // Create the conf file system
106        FS confFS = new FS();
107        for (File conf : confs) {
108          confFS.mount(conf);
109        }
110        confFS.mount(classLoader, Path.get("/crash/"));
111    
112        // The service loader discovery
113        ServiceLoaderDiscovery discovery = new ServiceLoaderDiscovery(classLoader);
114    
115        //
116        StringBuilder info = new StringBuilder("Booting crash with classpath=");
117        info.append(jars).append(" and mounts=[");
118        for (int i = 0;i < cmds.size();i++) {
119          if (i > 0) {
120            info.append(',');
121          }
122          info.append(cmds.get(i).getAbsolutePath());
123        }
124        info.append(']');
125        log.log(Level.INFO, info.toString());
126    
127        //
128        PluginContext context = new PluginContext(
129          discovery,
130          attributes,
131          cmdFS,
132          confFS,
133          classLoader);
134    
135        //
136        context.refresh();
137    
138        //
139        start(context);
140      }
141    
142      public void shutdown() {
143        stop();
144      }
145    }