SavedApplicationFactoryBean.java
001 /*
002  *  SavedApplicationFactoryBean.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, 22/Jan/2008
013  *
014  *  $Id: SavedApplicationFactoryBean.java 12940 2010-08-08 17:41:22Z ian_roberts $
015  */
016 
017 package gate.util.spring;
018 
019 import gate.Factory;
020 import gate.creole.ResourceInstantiationException;
021 import gate.util.GateException;
022 import gate.util.persistence.PersistenceManager;
023 
024 import java.io.File;
025 import java.io.IOException;
026 import java.net.URL;
027 import java.util.List;
028 
029 import org.springframework.beans.factory.DisposableBean;
030 import org.springframework.beans.factory.FactoryBean;
031 import org.springframework.core.io.Resource;
032 
033 /**
034  * Spring factory bean to load a saved GATE application from a Spring
035  * resource location. Typically used via the <code>gate:</code>
036  * extension namespace:
037  
038  <pre>
039  * &lt;gate:saved-application location=&quot;WEB-INF/application.gapp&quot; /&gt;
040  </pre>
041  
042  * See {@link Init} for details of how to declare this namespace in your
043  * bean definition files. We first attempt to resolve the location as a
044  * File, if this fails we fall back to resolving it as a URL. This is
045  * useful with servlet context resources (with an expanded web
046  * application) as it will give a <code>file:</code> URL rather than
047  * an opaque scheme like <code>jndi:</code> (Tomcat). The element also
048  * supports a nested <code>&lt;gate:customisers&gt;</code> element,
049  * giving a list of {@link ResourceCustomiser}s that will be applied to
050  * the application after it is loaded.
051  */
052 public class SavedApplicationFactoryBean extends GateAwareObject implements
053                                                                 FactoryBean,
054                                                                 DisposableBean {
055 
056   private Resource location;
057 
058   private List<ResourceCustomiser> customisers;
059 
060   private Object object = null;
061 
062   public void setLocation(Resource location) {
063     this.location = location;
064   }
065 
066   public void setCustomisers(List<ResourceCustomiser> customisers) {
067     this.customisers = customisers;
068   }
069 
070   /**
071    * Loads the saved application file and applies any registered
072    * customisers.
073    
074    @return the (possibly customised) application
075    */
076   public Object getObject() throws GateException, IOException {
077     if(object == null) {
078       ensureGateInit();
079 
080       object = PersistenceManager.loadObjectFromUrl(
081               SpringFactory.resourceToUrl(location));
082 
083       if(customisers != null) {
084         for(ResourceCustomiser c : customisers) {
085           try {
086             c.customiseResource((gate.Resource)object);
087           }
088           catch(GateException gx) {
089             throw gx;
090           }
091           catch(IOException ix) {
092             throw ix;
093           }
094           catch(RuntimeException rx) {
095             throw rx;
096           }
097           catch(Exception e) {
098             throw new ResourceInstantiationException(
099                     "Exception in resource customiser", e);
100           }
101         }
102       }
103     }
104 
105     return object;
106   }
107 
108   public Class getObjectType() {
109     return null;
110   }
111 
112   public boolean isSingleton() {
113     return true;
114   }
115 
116   /**
117    * Destroy the resource created by this bean, by passing it to
118    {@link Factory#deleteResource}.  This will in turn delete
119    * any PRs that the application contains.
120    */
121   public void destroy() throws Exception {
122     if(object != null && object instanceof gate.Resource) {
123       Factory.deleteResource((gate.Resource)object);
124     }
125   }
126 
127 }