Init.java
001 /*
002  *  Init.java
003  *
004  *  Copyright (c) 1995-2010, The University of Sheffield. See the file
005  *  COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
006  *
007  *  This file is part of GATE (see http://gate.ac.uk/), and is free
008  *  software, licenced under the GNU Library General Public License,
009  *  Version 2, June 1991 (in the distribution as file licence.html,
010  *  and also available at http://gate.ac.uk/gate/licence.html).
011  *
012  *  Ian Roberts, 07/Oct/2006
013  *
014  *  $Id: Init.java 13547 2011-03-22 16:54:55Z ian_roberts $
015  */
016 
017 package gate.util.spring;
018 
019 import gate.Gate;
020 import gate.util.GateException;
021 
022 import org.apache.log4j.Logger;
023 import org.springframework.beans.factory.BeanFactory;
024 import org.springframework.beans.factory.BeanFactoryAware;
025 import org.springframework.beans.factory.BeanFactoryUtils;
026 import org.springframework.beans.factory.ListableBeanFactory;
027 import org.springframework.core.io.Resource;
028 
029 import java.net.MalformedURLException;
030 import java.net.URL;
031 import java.io.File;
032 import java.io.IOException;
033 import java.util.List;
034 import java.util.Iterator;
035 
036 /**
037  <p>
038  * Helper class to support GATE initialisation via <a
039  * href="http://www.springframework.org">Spring</a>. The following is a
040  * typical XML fragment to initialise GATE.
041  </p>
042  
043  <pre>
044  * &lt;beans xmlns="http://www.springframework.org/schema/beans"
045  *        xmlns:gate="http://gate.ac.uk/ns/spring"
046  *        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
047  *        xsi:schemaLocation="
048  *          http://www.springframework.org/schema/beans
049  *          http://www.springframework.org/schema/beans/spring-beans.xsd
050  *          http://gate.ac.uk/ns/spring
051  *          http://gate.ac.uk/ns/spring.xsd"&gt;
052  
053  *   &lt;gate:init gate-home="path/to/GATE"
054  *              site-config-file="site/gate.xml"
055  *              user-config-file="user/gate.xml"&gt;
056  *     &lt;gate:preload-plugins&gt;
057  *       &lt;value&gt;plugins/ANNIE&lt;/value&gt;
058  *       &lt;value&gt;http://plugins.org/another/plugin&lt;/value&gt;
059  *     &lt;/gate:preload-plugins&gt;
060  *   &lt;/gate:init&gt;
061  </pre>
062  
063  <p>
064  * Valid attributes are <code>gate-home</code>,
065  <code>plugins-home</code><code>site-config-file</code>,
066  <code>user-config-file</code> and <code>builtin-creole-dir</code> -
067  * Spring <code>Resource</code>s corresponding to the equivalent static
068  * set methods of {@link gate.Gate}. Also, <code>preload-plugins</code>
069  * is a list of <code>Resource</code>s that will be loaded as GATE
070  * plugins after GATE is initialised.
071  </p>
072  
073  <p>
074  * As well as any plugins specified using <code>preload-plugins</code>,
075  * we also scan the defining bean factory for any beans of type
076  {@link ExtraGatePlugin}, and load the plugins they refer to. This is
077  * useful if bean definitions are provided in several separate files, or
078  * if you are providing additional bean definitions to a context that
079  * already defines an Init bean definition that you cannot edit.
080  </p>
081  
082  <p>
083  * The equivalent definition in "normal" Spring form (without the
084  <code>gate:</code> namespace) would be:
085  </p>
086  
087  <pre>
088  * &lt;bean class="gate.util.spring.Init"
089  *      init-method="init"&gt;
090  *   &lt;property name="gateHome" value="path/to/GATE" /&gt;
091  *   &lt;property name="siteConfigFile" value="site/gate.xml" /&gt;
092  *   &lt;property name="userConfigFile" value="user/gate.xml" /&gt;
093  *   &lt;property name="preloadPlugins"&gt;
094  *     &lt;list&gt;
095  *       &lt;value&gt;plugins/ANNIE&lt;/value&gt;
096  *       &lt;value&gt;http://plugins.org/another/plugin&lt;/value&gt;
097  *     &lt;/list&gt;
098  *   &lt;/property&gt;
099  * &lt;/bean&gt;
100  </pre>
101  
102  <b>Note that when using this form the init-method="init" in the above
103  * definition is vital. GATE will not work if it is omitted.</b>
104  */
105 public class Init implements BeanFactoryAware {
106   
107   private static final Logger log = Logger.getLogger(Init.class);
108 
109   /**
110    * An optional list of plugins to load after GATE initialisation.
111    */
112   private List<Resource> plugins;
113 
114   private BeanFactory beanFactory;
115 
116   public void setBeanFactory(BeanFactory beanFactory) {
117     this.beanFactory = beanFactory;
118   }
119 
120   public void setGateHome(Resource gateHomethrows IOException {
121     if(!Gate.isInitialised()) Gate.setGateHome(gateHome.getFile());
122   }
123 
124   public void setPluginsHome(Resource pluginsHomethrows IOException {
125     if(!Gate.isInitialised()) Gate.setPluginsHome(pluginsHome.getFile());
126   }
127 
128   public void setSiteConfigFile(Resource siteConfigFilethrows IOException {
129     if(!Gate.isInitialised()) Gate.setSiteConfigFile(siteConfigFile.getFile());
130   }
131 
132   public void setUserConfigFile(Resource userConfigFilethrows IOException {
133     if(!Gate.isInitialised()) Gate.setUserConfigFile(userConfigFile.getFile());
134   }
135 
136   public void setBuiltinCreoleDir(Resource builtinCreoleDirthrows IOException {
137     if(!Gate.isInitialised())
138       Gate.setBuiltinCreoleDir(builtinCreoleDir.getURL());
139   }
140 
141   public void setPreloadPlugins(List<Resource> plugins) {
142     this.plugins = plugins;
143   }
144 
145   /**
146    * Initialises GATE and loads any preloadPlugins that have been
147    * specified, as well as any defined by {@link ExtraGatePlugin} beans
148    * in the containing factory.
149    */
150   public void init() throws Exception {
151     if(!Gate.isInitialised()) {
152       log.info("Initialising GATE");
153       Gate.init();
154     }
155     else {
156       log.info("GATE already initialised");
157     }
158     if(plugins != null && !plugins.isEmpty()) {
159       for(Resource plugin : plugins) {
160         log.debug("Loading preload-plugin " + plugin);
161         loadPlugin(plugin);
162       }
163     }
164     // look for any ExtraGatePlugin beans
165     if(beanFactory instanceof ListableBeanFactory) {
166       String[] extraPluginBeanNames = BeanFactoryUtils
167               .beanNamesForTypeIncludingAncestors(
168                       (ListableBeanFactory)beanFactory, ExtraGatePlugin.class);
169       for(String name : extraPluginBeanNames) {
170         Resource plugin = ((ExtraGatePlugin)beanFactory.getBean(name,
171                 ExtraGatePlugin.class)).getLocation();
172         if(plugin != null) {
173           log.debug("Loading extra-plugin " + plugin);
174           loadPlugin(plugin);
175         }
176       }
177     }
178   // init()
179 
180   private void loadPlugin(Resource pluginthrows GateException, IOException,
181           MalformedURLException {
182     File pluginFile = null;
183     try {
184       pluginFile = plugin.getFile();
185     }
186     catch(IOException e) {
187       // no problem, try just as URL
188     }
189 
190     if(pluginFile == null) {
191       Gate.getCreoleRegister().registerDirectories(plugin.getURL());
192     }
193     else {
194       Gate.getCreoleRegister().registerDirectories(pluginFile.toURI().toURL());
195     }
196   }
197 }