KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > portal > core > theme > deployment > jboss > LayoutDeployment


1 /*****************************************
2  * *
3  * JBoss Portal: The OpenSource Portal *
4  * *
5  * Distributable under LGPL license. *
6  * See terms of license at gnu.org. *
7  * *
8  *****************************************/

9 package org.jboss.portal.core.theme.deployment.jboss;
10
11 import org.apache.log4j.Logger;
12 import org.apache.xpath.CachedXPathAPI;
13 import org.jboss.deployment.DeploymentException;
14 import org.jboss.portal.common.util.Loader;
15 import org.jboss.portal.common.util.Tools;
16 import org.jboss.portal.common.util.XML;
17 import org.jboss.portal.core.theme.impl.PortalLayoutImpl;
18 import org.jboss.portal.core.theme.render.RendererFactory;
19 import org.jboss.portal.server.LayoutServer;
20 import org.jboss.portal.server.ServerManager;
21 import org.jboss.portal.server.ServerRegistrationID;
22 import org.jboss.portal.server.deployment.PortalWebApp;
23 import org.jboss.portal.server.deployment.jboss.Deployment;
24 import org.jboss.portal.server.metadata.LayoutRegistrationMetaData;
25 import org.jboss.portal.server.theme.LayoutException;
26 import org.jboss.portal.server.theme.PortalLayout;
27 import org.jboss.portal.server.theme.PortalRenderSet;
28 import org.jboss.portal.server.theme.strategy.AbstractLayoutStrategy;
29 import org.w3c.dom.Document JavaDoc;
30 import org.w3c.dom.NodeList JavaDoc;
31 import org.xml.sax.SAXException JavaDoc;
32
33 import javax.activation.MimeTypeParseException JavaDoc;
34 import javax.xml.parsers.ParserConfigurationException JavaDoc;
35 import javax.xml.transform.TransformerException JavaDoc;
36 import java.io.File JavaDoc;
37 import java.io.FileOutputStream JavaDoc;
38 import java.io.IOException JavaDoc;
39 import java.io.InputStream JavaDoc;
40 import java.net.URL JavaDoc;
41 import java.util.ArrayList JavaDoc;
42 import java.util.HashMap JavaDoc;
43 import java.util.List JavaDoc;
44 import java.util.Map JavaDoc;
45
46 /**
47  * Deploy the layouts contained in a WebApplication.
48  * <p>A Web Application can define layouts to be offered to the portal. Layouts are JSPs or Servlets, that
49  * take over the job of presenting the rendered content of a portal request to the end device. Layouts need to be
50  * announced to the portal via the /WEB-INF/portal-layouts.xml descriptor (see also portal-layouts.dtd)</p>
51  *
52  * @author <a HREF="mailto:mholzner@novell.com">Martin Holzner</a>
53  * @version $Revision: 1.14 $
54  */

55 public class LayoutDeployment extends Deployment
56 {
57    private static Logger log = Logger.getLogger(LayoutDeployment.class);
58    private final ServerManager serverManager;
59
60    /**
61     * Construct the deployer.
62     *
63     * @param serverManager
64     * @param url
65     * @param pwa
66     * @param appName
67     */

68    public LayoutDeployment(ServerManager serverManager, URL JavaDoc url, PortalWebApp pwa, String JavaDoc appName)
69    {
70       super(serverManager, url, pwa, appName);
71       this.serverManager = serverManager;
72       log.info("new layout deployer for : " + appName);
73    }
74
75    /**
76     * Create the resources from this portal web application.
77     *
78     * @throws DeploymentException if anything goes wrong
79     */

80    public void create() throws DeploymentException
81    {
82       log.info("create new layout(s), found in : " + appName);
83
84       try
85       {
86          // first check for the defaults
87
// see if there are any named rendersets
88
InputStream JavaDoc layoutStream = pwa.getServletContext().getResourceAsStream("/WEB-INF/layout/portal-renderSet.xml");
89          if (layoutStream != null)
90          {
91             log.info("found default render set ...");
92             Document JavaDoc renderSetDoc = XML.createDocument(layoutStream);
93             addNamedRenderSets(pwa.getClassLoader(), renderSetDoc);
94          }
95
96          // now see if there are any named strategies
97
layoutStream = pwa.getServletContext().getResourceAsStream("/WEB-INF/layout/portal-strategies.xml");
98          if (layoutStream != null)
99          {
100             log.info("found default strategy ...");
101             Document JavaDoc strategiesDoc = XML.createDocument(layoutStream);
102             addNamedStrategies(pwa.getClassLoader(), strategiesDoc);
103          }
104
105          // now check the individual layouts
106
layoutStream = pwa.getServletContext().getResourceAsStream("/WEB-INF/portal-layouts.xml");
107
108          if (layoutStream == null)
109          {
110             return;
111          }
112
113          Document JavaDoc layouts = XML.createDocument(layoutStream);
114          addLayouts(layouts);
115
116          log.info("done creating new layout(s), found in : " + appName);
117       }
118       catch (TransformerException JavaDoc e)
119       {
120          throw new DeploymentException(e);
121       }
122       catch (IOException JavaDoc e)
123       {
124          throw new DeploymentException(e);
125       }
126       catch (ParserConfigurationException JavaDoc e)
127       {
128          throw new DeploymentException(e);
129       }
130       catch (SAXException JavaDoc e)
131       {
132          throw new DeploymentException(e);
133       }
134       catch (LayoutException e)
135       {
136          throw new DeploymentException(e);
137       }
138    }
139
140    /**
141     * Destroy (and remove) all the resources from this portal web application that are registered with the portal.
142     *
143     * @throws DeploymentException if anything goes wrong
144     */

145    public void destroy() throws DeploymentException
146    {
147       log.info("destroying layout(s), found in : " + appName);
148       try
149       {
150          LayoutServer server = serverManager.getLayoutServer();
151          server.removeLayouts(appName);
152          server.removeRenderSets(appName);
153          server.removeStrategies(appName);
154       }
155       catch (LayoutException e)
156       {
157          throw new DeploymentException(e);
158       }
159       log.info("done destroying layout(s), found in : " + appName);
160    }
161
162    private void addLayouts(Document JavaDoc layouts)
163       throws DeploymentException, TransformerException JavaDoc, LayoutException
164    {
165       CachedXPathAPI xpath = new CachedXPathAPI();
166
167       // get the strategies , if any are defined
168
Map JavaDoc strategies = getStrategies(layouts, xpath);
169       List JavaDoc renderSets = getRenderSets(layouts, xpath);
170
171       NodeList JavaDoc nl = xpath.selectNodeList(layouts, "/layouts/layout");
172
173       // if there is at least one defined layout, make sure that the portal-layout.tld is available in the local context
174
if (nl.getLength() > 0)
175       {
176          File JavaDoc targetContextRoot = new File JavaDoc(pwa.getServletContext().getRealPath("/WEB-INF"));
177          if (targetContextRoot.exists() && targetContextRoot.isDirectory())
178          {
179             copyWebInfResources(targetContextRoot, getServerManager().getConfiguration(),
180                "/theme", "/portal-layout.tld");
181 // copyWebInfResources(targetContextRoot, getServerManager().getConfiguration(),
182
// "/theme", "/portal-renderSet.xml");
183
}
184          else
185          {
186             log.warn("Cannot access the WEB-INF folder for the deployed application: " + appName);
187          }
188       }
189
190       for (int i = 0; i < nl.getLength(); i++)
191       {
192          String JavaDoc name = xpath.selectSingleNode(nl.item(i), "./name/text()").getNodeValue();
193          String JavaDoc uri = null;
194          Map JavaDoc stateURIMap = new HashMap JavaDoc();
195          NodeList JavaDoc stateURIs = xpath.selectNodeList(nl.item(i), "./uri");
196          for (int j = 0; j < stateURIs.getLength(); j++)
197          {
198             if (xpath.selectSingleNode(stateURIs.item(j), "@state") == null)
199             {
200                uri = xpath.selectSingleNode(stateURIs.item(j), "./text()").getNodeValue();
201             }
202             else
203             {
204                String JavaDoc state = xpath.selectSingleNode(stateURIs.item(j), "@state").getNodeValue();
205                String JavaDoc stateURI = xpath.selectSingleNode(stateURIs.item(j), "./text()").getNodeValue();
206                stateURIMap.put(state, stateURI);
207             }
208          }
209
210          // create the layout meta info and add it to the server
211
PortalLayout layout = createLayout(pwa, appName, name, uri, stateURIMap, renderSets, strategies);
212          serverManager.getLayoutServer().addLayout((LayoutRegistrationMetaData)layout);
213       }
214    }
215
216    private void addNamedStrategies(ClassLoader JavaDoc loader, Document JavaDoc strategiesDoc) throws DeploymentException
217    {
218       CachedXPathAPI xpath = new CachedXPathAPI();
219
220       try
221       {
222          NodeList JavaDoc strategieSetList = xpath.selectNodeList(strategiesDoc, "//portal-strategies/set");
223
224          for (int i = 0; i < strategieSetList.getLength(); i++)
225          {
226             String JavaDoc strategyName = xpath.selectSingleNode(strategieSetList.item(i), "./@name").getNodeValue();
227             NodeList JavaDoc strategieList = xpath.selectNodeList(strategieSetList.item(i), "./strategy");
228             for (int j = 0; j < strategieList.getLength(); j++)
229             {
230                AbstractLayoutStrategy strategy = RendererFactory.getLayoutStrategy(loader, xpath, strategieList.item(j));
231                log.info("found: " + strategy);
232                strategy.setAppName(appName);
233                strategy.setName(strategyName);
234                serverManager.getLayoutServer().addStrategy(strategy);
235             }
236          }
237       }
238       catch (TransformerException JavaDoc e)
239       {
240          throw new DeploymentException(e);
241       }
242       catch (IllegalAccessException JavaDoc e)
243       {
244          throw new DeploymentException(e);
245       }
246       catch (MimeTypeParseException JavaDoc e)
247       {
248          throw new DeploymentException(e);
249       }
250       catch (InstantiationException JavaDoc e)
251       {
252          throw new DeploymentException(e);
253       }
254       catch (ClassNotFoundException JavaDoc e)
255       {
256          throw new DeploymentException(e);
257       }
258    }
259
260    private void addNamedRenderSets(ClassLoader JavaDoc loader, Document JavaDoc renderSetDoc) throws DeploymentException
261    {
262       CachedXPathAPI xpath = new CachedXPathAPI();
263
264       try
265       {
266          NodeList JavaDoc sets = xpath.selectNodeList(renderSetDoc, "//portal-renderSet/renderSet");
267          for (int i = 0; i < sets.getLength(); i++)
268          {
269             String JavaDoc renderSetName = xpath.selectSingleNode(sets.item(i), "@name").getNodeValue();
270
271             NodeList JavaDoc setList = xpath.selectNodeList(sets.item(i), "./set");
272             for (int j = 0; j < setList.getLength(); j++)
273             {
274                PortalRenderSet renderSet = RendererFactory.getRenderSet(appName, renderSetName, loader, xpath, setList.item(j));
275                log.info("found: " + renderSet);
276                serverManager.getLayoutServer().addRenderSet(renderSet);
277             }
278          }
279       }
280       catch (TransformerException JavaDoc e)
281       {
282          throw new DeploymentException(e);
283       }
284       catch (IllegalAccessException JavaDoc e)
285       {
286          throw new DeploymentException(e);
287       }
288       catch (MimeTypeParseException JavaDoc e)
289       {
290          throw new DeploymentException(e);
291       }
292       catch (ClassNotFoundException JavaDoc e)
293       {
294          throw new DeploymentException(e);
295       }
296       catch (InstantiationException JavaDoc e)
297       {
298          throw new DeploymentException(e);
299       }
300    }
301
302    private List JavaDoc getRenderSets(Document JavaDoc layouts, CachedXPathAPI xpath)
303       throws DeploymentException
304    {
305       log.debug("adding rendersets...");
306       List JavaDoc renderSets = new ArrayList JavaDoc();
307
308       // check if there is a render set defined in this layout descriptor
309
try
310       {
311          NodeList JavaDoc renderSet = xpath.selectNodeList(layouts, "//layouts/renderSet/set");
312          for (int i = 0; i < renderSet.getLength(); i++)
313          {
314             PortalRenderSet portalRenderSet = null;
315             portalRenderSet = RendererFactory.getRenderSet(appName, null, pwa.getClassLoader(), xpath, renderSet.item(i));
316             if (portalRenderSet != null)
317             {
318                log.debug("adding : " + portalRenderSet);
319                renderSets.add(portalRenderSet);
320             }
321          }
322          return renderSets;
323       }
324       catch (IllegalAccessException JavaDoc e)
325       {
326          throw new DeploymentException(e);
327       }
328       catch (InstantiationException JavaDoc e)
329       {
330          throw new DeploymentException(e);
331       }
332       catch (ClassNotFoundException JavaDoc e)
333       {
334          throw new DeploymentException(e);
335       }
336       catch (TransformerException JavaDoc e)
337       {
338          throw new DeploymentException(e);
339       }
340       catch (MimeTypeParseException JavaDoc e)
341       {
342          throw new DeploymentException(e);
343       }
344    }
345
346
347    private Map JavaDoc getStrategies(Document JavaDoc layouts, CachedXPathAPI xpath) throws DeploymentException
348    {
349       log.debug("adding strategies...");
350       Map JavaDoc strategies = new HashMap JavaDoc();
351
352       NodeList JavaDoc strategyNodes = null;
353       try
354       {
355          strategyNodes = xpath.selectNodeList(layouts, "//layouts/strategy");
356
357          for (int i = 0; i < strategyNodes.getLength(); i++)
358          {
359             AbstractLayoutStrategy strategy = RendererFactory.getLayoutStrategy(pwa.getClassLoader(), xpath, strategyNodes.item(i));
360             if (strategy != null)
361             {
362                log.debug("adding : " + strategy);
363                strategy.setAppName(appName);
364                strategies.put(strategy.getMediaType(), strategy);
365             }
366          }
367
368          return strategies;
369       }
370       catch (TransformerException JavaDoc e)
371       {
372          throw new DeploymentException(e);
373       }
374       catch (MimeTypeParseException JavaDoc e)
375       {
376          throw new DeploymentException(e);
377       }
378       catch (ClassNotFoundException JavaDoc e)
379       {
380          throw new DeploymentException(e);
381       }
382       catch (IllegalAccessException JavaDoc e)
383       {
384          throw new DeploymentException(e);
385       }
386       catch (InstantiationException JavaDoc e)
387       {
388          throw new DeploymentException(e);
389       }
390    }
391
392    private PortalLayout createLayout(PortalWebApp pwa, String JavaDoc appName, String JavaDoc name, String JavaDoc uri,
393                                      Map JavaDoc stateURIMap, List JavaDoc renderSets, Map JavaDoc strategies)
394    {
395       if (pwa == null || name == null)
396       {
397          throw new NullPointerException JavaDoc("ServletContext[" + pwa + "] name[" + name + "]");
398       }
399
400       ServerRegistrationID id = ServerRegistrationID.createID(ServerRegistrationID.TYPE_LAYOUT, new String JavaDoc[]{appName, name});
401       return new PortalLayoutImpl(id, pwa, appName, name, uri, stateURIMap, renderSets, strategies);
402    }
403
404    /**
405     * web apps that get deployed and have layouts in them, might need the
406     * portal-layouts.tld to resolve the theme and layout tags in the layout jsps
407     * That's why we copy them here into the app that is in the process of being deployed
408     *
409     * @param targetContextRoot the File of the target WEB-INF folder
410     * @param fileURI the uri of the resource to copy (from the sar to the deployed web app)
411     */

412    private void copyWebInfResources(File JavaDoc targetContextRoot, Loader loader, String JavaDoc folderURI, String JavaDoc fileURI) throws DeploymentException
413    {
414
415       // first some sanity checks
416
File JavaDoc folder = new File JavaDoc(targetContextRoot, folderURI);
417       if (folder.exists() && !folder.isDirectory())
418       {
419          throw new DeploymentException("/WEB-INF/" + folderURI + " needs to be a directory to support layouts in this archive");
420       }
421       else if (!folder.exists())
422       {
423          log.info("creating /WEB-INF" + folderURI + " folder for this archive");
424          folder.mkdir();
425       }
426
427       InputStream JavaDoc source = null;
428       FileOutputStream JavaDoc target = null;
429       try
430       {
431          final String JavaDoc fileLocation = folderURI + fileURI;
432          File JavaDoc targetFile = new File JavaDoc(folder, fileURI);
433          if (targetFile.exists())
434          {
435 // it's already there, nothing to copy
436
log.debug("nothing to copy; file already exists in context : " + fileLocation);
437             return;
438          }
439
440 // now copy the layouts tld from the sar to the deployed app, so that jsps inside that app can use the
441
// layout and theme tags
442
// source = Thread.currentThread().getContextClassLoader().getResourceAsStream("org/jboss/portal/core/theme/" + fileURI);
443
source = loader.load(fileLocation);
444          log.debug("got the source : " + (source != null));
445          target = new FileOutputStream JavaDoc(targetFile);
446          log.debug("got the target : " + (target != null));
447          Tools.copy(source, target);
448          log.debug("WEB-INF resource file: " + fileURI);
449       }
450       catch (IOException JavaDoc e)
451       {
452          log.error("", e);
453       }
454       finally
455       {
456          Tools.safeClose(source);
457          Tools.safeClose(target);
458       }
459    }
460 }
461
Popular Tags