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