View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.jetspeed.deployment.impl;
18  
19  import java.io.File;
20  import java.io.FileFilter;
21  import java.io.FileNotFoundException;
22  import java.io.IOException;
23  import java.net.URL;
24  import java.net.URLClassLoader;
25  import java.util.ArrayList;
26  
27  import org.apache.commons.logging.Log;
28  import org.apache.commons.logging.LogFactory;
29  import org.apache.jetspeed.components.portletregistry.PortletRegistry;
30  import org.apache.jetspeed.deployment.DeploymentEvent;
31  import org.apache.jetspeed.deployment.DeploymentEventListener;
32  import org.apache.jetspeed.deployment.DeploymentException;
33  import org.apache.jetspeed.deployment.DeploymentStatus;
34  import org.apache.jetspeed.tools.deploy.JetspeedDeploy;
35  import org.apache.jetspeed.tools.pamanager.PortletApplicationManagement;
36  import org.apache.jetspeed.util.DirectoryHelper;
37  
38  /***
39   * <p>
40   * DeployportletAppEventListener
41   * </p>
42   * 
43   * @author <a href="mailto:weaver@apache.org">Scott T. Weaver </a>
44   * @version $Id: DeployPortletAppEventListener.java 548891 2007-06-20 02:24:37Z ate $
45   */
46  public class DeployPortletAppEventListener implements DeploymentEventListener
47  {
48  
49      protected static final Log           log = LogFactory.getLog("deployment");
50      private String                       webAppDir;
51      private int                           localPAPrefixLength;
52      private String                       localAppDir;
53      private String                       localAppStagingDir;
54      private boolean                      stripLoggers;
55      private PortletApplicationManagement pam;
56      /***
57       * @param pam
58       * @param webAppDir
59       * @param localAppDir
60       * @param stripLoggers
61       * @throws FileNotFoundException the <code>webAppDir</code> or <code>localAppDir</code> directory does not
62       *                               exist.
63       */
64      public DeployPortletAppEventListener(PortletApplicationManagement pam, PortletRegistry registry, String webAppDir,
65                                           String localAppDir, boolean stripLoggers) throws FileNotFoundException
66      {
67          this(pam,registry,webAppDir,localAppDir,null,stripLoggers);
68      }
69      /***
70       * @param pam
71       * @param webAppDir
72       * @param localAppDir
73       * @param localAppStagingDir
74       * @param stripLoggers
75       * @throws FileNotFoundException the <code>webAppDir</code> or <code>localAppDir</code> directory does not
76       *                               exist.
77       */
78      public DeployPortletAppEventListener(PortletApplicationManagement pam, PortletRegistry registry, String webAppDir,
79                                           String localAppDir, String localAppStagingDir, boolean stripLoggers) throws FileNotFoundException
80      {
81          this.pam = pam;
82          this.stripLoggers = stripLoggers;
83          localPAPrefixLength = PortletApplicationManagement.LOCAL_PA_PREFIX.length();
84  
85          File webAppDirFile = new File(webAppDir);
86  
87          if (webAppDirFile.exists())
88          {
89              try
90              {
91                  this.webAppDir = webAppDirFile.getCanonicalPath();
92              }
93              catch (IOException e) {}
94          }
95          else
96          {
97              throw new FileNotFoundException("The depoyment directory for portlet applications \""
98                                              + webAppDirFile.getAbsolutePath() + "\" does not exist.");
99          }
100         File localAppDirFile = new File(localAppDir);
101 
102         if (!localAppDirFile.exists())
103         {
104             localAppDirFile.mkdirs();
105         }
106         else if (!localAppDirFile.isDirectory())
107         {
108             throw new FileNotFoundException("Invalid depoyment directory for local portlet applications: \""
109                                             + localAppDirFile.getAbsolutePath());
110         }
111         try
112         {
113             this.localAppDir = localAppDirFile.getCanonicalPath();
114         }
115         catch (IOException e) {}
116         if ( localAppStagingDir != null )
117         {
118             File localAppStagingDirFile = new File(localAppStagingDir);
119             if ( !localAppStagingDirFile.exists() )
120             {
121                 localAppStagingDirFile.mkdirs();
122             }
123             else if (!localAppStagingDirFile.isDirectory())
124             {
125                 throw new FileNotFoundException("Invalid staging directory for local portlet applications: \""
126                         + localAppStagingDirFile.getAbsolutePath());
127             }
128             try
129             {
130                 this.localAppStagingDir = localAppStagingDirFile.getCanonicalPath();
131             }
132             catch (IOException e) {}
133         }
134     }
135 
136     protected String getWebAppDir()
137     {
138         return webAppDir;
139     }
140     
141     public void initialize()
142     {
143         // start deployed local pa
144         File[] localApps = new File(localAppDir).listFiles(new FileFilter()
145         {
146             public boolean accept(File pathname)
147             {
148                 return pathname.isDirectory();
149             }
150         });
151         for (int i = 0; i < localApps.length; i++)
152         {
153             // Check for at least WEB-INF/portlet.xml
154             // This will also prevent the src/webapps/WEB-INF/apps/CVS folder
155             // to be seen as local app from testcases resulting in an exception
156             if ( ! new File(localApps[i],"WEB-INF/portlet.xml").exists() )
157             {
158                 log.warn("Not a local application " + localApps[i].getName());
159             }
160             else
161             {
162                 DirectoryHelper paDirHelper = new DirectoryHelper(localApps[i]);
163                 try
164                 {
165                     pam.startLocalPortletApplication(localApps[i].getName(), paDirHelper,
166                                                      createLocalPAClassLoader(localApps[i]));
167                 }
168                 catch (Exception e)
169                 {
170                     log.error("Failed to start Local Portlet Application " + localApps[i], e);
171                 }
172             }
173         }
174     }
175     
176     private String getEventParentPath(DeploymentEvent event)
177     {
178         try
179         {
180             return event.getDeploymentObject().getFile().getParentFile().getCanonicalPath();
181         }
182         catch (IOException io)
183         {
184             return null;
185         }
186     }
187 
188     /***
189      * <p>
190      * invokeDeploy
191      * </p>
192      * 
193      * @param event
194      * @throws DeploymentException
195      */
196     public void invokeDeploy(DeploymentEvent event) throws DeploymentException
197     {
198         String fileName = event.getName();
199         if (fileName.endsWith(".war"))
200         {
201             if ((localAppStagingDir != null && getEventParentPath(event).equals(localAppStagingDir))
202                     || (fileName.length() > localPAPrefixLength && fileName.substring(0, localPAPrefixLength)
203                             .equalsIgnoreCase(PortletApplicationManagement.LOCAL_PA_PREFIX)))
204             {
205                 deployLocalPortletApplication(event);
206             }
207             else
208             {
209                 deployPortletApplication(event);
210             }
211         }
212     }
213 
214     protected void deployPortletApplication(DeploymentEvent event) throws DeploymentException
215     {
216         try
217         {
218             File toFile = new File(webAppDir, event.getName());
219             new JetspeedDeploy(event.getPath(), toFile.getAbsolutePath(), stripLoggers);
220             event.setStatus(DeploymentStatus.STATUS_OKAY);
221         }
222         catch (Exception e)
223         {
224             throw new DeploymentException(e);
225         }
226     }
227 
228     protected void deployLocalPortletApplication(DeploymentEvent event) throws DeploymentException
229     {
230         try
231         {
232             String fileName = event.getName();
233             String appName = fileName.substring(0, fileName.length() - 4);
234             pam.stopLocalPortletApplication(appName);
235             File targetDir = new File(localAppDir, appName);
236             JarExpander.expand(event.getDeploymentObject().getFile(), targetDir);
237             DirectoryHelper paDirHelper = new DirectoryHelper(targetDir);
238             pam.startLocalPortletApplication(appName, paDirHelper, createLocalPAClassLoader(targetDir));
239             event.setStatus(DeploymentStatus.STATUS_OKAY);
240         }
241         catch (Exception e)
242         {
243             throw new DeploymentException(e);
244         }
245     }
246 
247     protected ClassLoader createLocalPAClassLoader(File paDir) throws IOException
248     {
249         ArrayList urls = new ArrayList();
250         File webInfClasses = null;
251 
252         webInfClasses = new File(paDir, ("WEB-INF/classes/"));
253         if (webInfClasses.exists())
254         {
255             log.info("Adding " + webInfClasses.toURL() + " to class path for Local PA " + paDir.getName());
256             urls.add(webInfClasses.toURL());
257         }
258 
259         File webInfLib = new File(paDir, "WEB-INF/lib");
260 
261         if (webInfLib.exists())
262         {
263             File[] jars = webInfLib.listFiles();
264 
265             for (int i = 0; i < jars.length; i++)
266             {
267                 File jar = jars[i];
268                 log.info("Adding " + jar.toURL() + " to class path for Local PA " + paDir.getName());
269                 urls.add(jar.toURL());
270             }
271         }
272         return new URLClassLoader((URL[]) urls.toArray(new URL[urls.size()]), getClass().getClassLoader());
273     }
274 
275 }