Coverage report

  %line %branch
org.apache.jetspeed.util.descriptor.PortletApplicationWar$1
0% 
0% 

 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.util.descriptor;
 18  
 
 19  
 import java.io.BufferedInputStream;
 20  
 import java.io.File;
 21  
 import java.io.FileFilter;
 22  
 import java.io.FileInputStream;
 23  
 import java.io.FileNotFoundException;
 24  
 import java.io.FileOutputStream;
 25  
 import java.io.FileWriter;
 26  
 import java.io.IOException;
 27  
 import java.io.InputStream;
 28  
 import java.io.InputStreamReader;
 29  
 import java.io.OutputStream;
 30  
 import java.io.OutputStreamWriter;
 31  
 import java.io.Reader;
 32  
 import java.io.UnsupportedEncodingException;
 33  
 import java.io.Writer;
 34  
 import java.net.MalformedURLException;
 35  
 import java.net.URL;
 36  
 import java.net.URLClassLoader;
 37  
 import java.util.ArrayList;
 38  
 import java.util.Collection;
 39  
 import java.util.Iterator;
 40  
 import java.util.List;
 41  
 
 42  
 import org.apache.commons.logging.Log;
 43  
 import org.apache.commons.logging.LogFactory;
 44  
 import org.apache.jetspeed.Jetspeed;
 45  
 import org.apache.jetspeed.om.common.portlet.MutablePortletApplication;
 46  
 import org.apache.jetspeed.om.common.servlet.MutableWebApplication;
 47  
 import org.apache.jetspeed.tools.deploy.JetspeedWebApplicationRewriter;
 48  
 import org.apache.jetspeed.tools.deploy.JetspeedWebApplicationRewriterFactory;
 49  
 import org.apache.jetspeed.tools.pamanager.PortletApplicationException;
 50  
 import org.apache.jetspeed.util.DirectoryHelper;
 51  
 import org.apache.jetspeed.util.FileSystemHelper;
 52  
 import org.apache.jetspeed.util.MultiFileChecksumHelper;
 53  
 import org.apache.pluto.om.common.SecurityRoleRef;
 54  
 import org.apache.pluto.om.common.SecurityRoleRefSet;
 55  
 import org.apache.pluto.om.common.SecurityRoleSet;
 56  
 import org.apache.pluto.om.portlet.PortletDefinition;
 57  
 import org.jdom.Document;
 58  
 import org.jdom.input.SAXBuilder;
 59  
 import org.jdom.output.Format;
 60  
 import org.jdom.output.XMLOutputter;
 61  
 import org.xml.sax.EntityResolver;
 62  
 import org.xml.sax.InputSource;
 63  
 import org.xml.sax.SAXException;
 64  
 
 65  
 /**
 66  
  * <p>
 67  
  * This class facilitates operations a portlet applications WAR file or WAR
 68  
  * file-like structure.
 69  
  * </p>
 70  
  * <p>
 71  
  * This class is utility class used mainly implementors of
 72  
  * {@link org.apache.jetspeed.pamanager.Deployment}and
 73  
  * {@link org.apache.jetspeed.pamanager.Registration}to assist in deployment
 74  
  * and undeployment of portlet applications.
 75  
  * 
 76  
  * @author <a href="mailto:sweaver@einnovation.com">Scott T. Weaver </a>
 77  
  * @author <a href="mailto:mavery@einnovation.com">Matt Avery </a>
 78  
  * @version $Id: PortletApplicationWar.java,v 1.10 2004/07/06 16:56:19 weaver
 79  
  *          Exp $
 80  
  */
 81  
 public class PortletApplicationWar
 82  
 {
 83  
     protected static final String WEB_XML_STRING = 
 84  
             "<?xml version='1.0' encoding='ISO-8859-1'?>" +
 85  
             "<!DOCTYPE web-app " +
 86  
             "PUBLIC '-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN' " + 
 87  
            "'http://java.sun.com/dtd/web-app_2_3.dtd'>\n" +
 88  
             "<web-app></web-app>";
 89  
 
 90  
     public static final String PORTLET_XML_PATH = "WEB-INF/portlet.xml";
 91  
     public static final String WEB_XML_PATH = "WEB-INF/web.xml";
 92  
     public static final String EXTENDED_PORTLET_XML_PATH = "WEB-INF/jetspeed-portlet.xml";
 93  
 
 94  
     protected static final int MAX_BUFFER_SIZE = 1024;
 95  
 
 96  
     public static final String JETSPEED_SERVLET_XPATH = "/web-app/servlet/servlet-name[contains(child::text(), \"JetspeedContainer\")]";
 97  
     public static final String JETSPEED_SERVLET_MAPPING_XPATH = "/web-app/servlet-mapping/servlet-name[contains(child::text(), \"JetspeedContainer\")]";
 98  
 
 99  
     protected static final Log log = LogFactory.getLog("deployment");
 100  
 
 101  
     protected String paName;
 102  
     protected String webAppContextRoot;
 103  
     protected FileSystemHelper warStruct;
 104  
     private MutableWebApplication webApp;
 105  
     private MutablePortletApplication portletApp;
 106  
     private long paChecksum;
 107  
     protected final List openedResources;
 108  
 
 109  
     protected static final String[] ELEMENTS_BEFORE_SERVLET = new String[]{"icon", "display-name", "description",
 110  
             "distributable", "context-param", "filter", "filter-mapping", "listener", "servlet"};
 111  
     protected static final String[] ELEMENTS_BEFORE_SERVLET_MAPPING = new String[]{"icon", "display-name",
 112  
             "description", "distributable", "context-param", "filter", "filter-mapping", "listener", "servlet",
 113  
             "servlet-mapping"};
 114  
 
 115  
     /**
 116  
      * @param warFile
 117  
      *            {@link org.apache.jetspeed.util.FileSystemHelper}representing
 118  
      *            the WAR file we are working with. This
 119  
      *            <code>FileSystemHelper</code> can be an actual WAR file or a
 120  
      *            directory structure layed out in a WAR-like fashion. name of
 121  
      *            the portlet application the <code>warPath</code> contains
 122  
      * @param webAppContextRoot
 123  
      *            context root relative to the servlet container of this app
 124  
      */
 125  
     public PortletApplicationWar( FileSystemHelper warStruct, String paName, String webAppContextRoot )
 126  
     {
 127  
         this(warStruct, paName, webAppContextRoot, 0);
 128  
     }
 129  
 
 130  
     public PortletApplicationWar( FileSystemHelper warStruct, String paName, String webAppContextRoot, long paChecksum )
 131  
     {
 132  
         validatePortletApplicationName(paName);
 133  
 
 134  
         this.paName = paName;
 135  
         this.webAppContextRoot = webAppContextRoot;
 136  
         this.openedResources = new ArrayList();
 137  
         this.warStruct = warStruct;
 138  
         this.paChecksum = paChecksum;
 139  
     }
 140  
     
 141  
     public long getPortletApplicationChecksum() throws IOException
 142  
     {
 143  
         if ( this.paChecksum == 0)
 144  
         {
 145  
             this.paChecksum = MultiFileChecksumHelper.getChecksum(new File[] {
 146  
                     new File(warStruct.getRootDirectory(), WEB_XML_PATH),
 147  
                     new File(warStruct.getRootDirectory(), PORTLET_XML_PATH),
 148  
                     new File(warStruct.getRootDirectory(), EXTENDED_PORTLET_XML_PATH) });
 149  
         }
 150  
         if (this.paChecksum == 0)
 151  
         {
 152  
           throw new IOException("Cannot find any deployment descriptor for Portlet Application "+paName);
 153  
         }
 154  
       return paChecksum;
 155  
     }
 156  
 
 157  
     /**
 158  
      * <p>
 159  
      * validatePortletApplicationName
 160  
      * </p>
 161  
      * 
 162  
      * @param paName
 163  
      */
 164  
     private void validatePortletApplicationName( String paName )
 165  
     {
 166  
         if (paName == null || paName.startsWith("/") || paName.startsWith("\\") || paName.endsWith("/")
 167  
                 || paName.endsWith("\\"))
 168  
         {
 169  
             throw new IllegalStateException("Invalid paName \"" + paName
 170  
                     + "\".  paName cannot be null nor can it begin nor end with any slashes.");
 171  
         }
 172  
     }
 173  
 
 174  
     /**
 175  
      * 
 176  
      * <p>
 177  
      * createWebApp
 178  
      * </p>
 179  
      * Creates a web applicaiton object based on the values in this WAR's
 180  
      * WEB-INF/web.xml
 181  
      * 
 182  
      * @return @throws
 183  
      *         PortletApplicationException
 184  
      * @throws IOException
 185  
      * @see org.apache.jetspeed.util.descriptor.WebApplicationDescriptor
 186  
      */
 187  
     public MutableWebApplication createWebApp() throws PortletApplicationException, IOException
 188  
     {
 189  
         Reader webXmlReader = getReader(WEB_XML_PATH);
 190  
 
 191  
         try
 192  
         {
 193  
             WebApplicationDescriptor webAppDescriptor = new WebApplicationDescriptor(webXmlReader, webAppContextRoot);
 194  
             webApp = webAppDescriptor.createWebApplication();
 195  
             return webApp;
 196  
         }
 197  
 
 198  
         finally
 199  
         {
 200  
             try
 201  
             {
 202  
                 if (webXmlReader != null)
 203  
                 {
 204  
                     webXmlReader.close();
 205  
                 }
 206  
             }
 207  
             catch (IOException e1)
 208  
             {
 209  
                 e1.printStackTrace();
 210  
             }
 211  
         }
 212  
 
 213  
     }
 214  
 
 215  
     /**
 216  
      * 
 217  
      * <p>
 218  
      * createPortletApp
 219  
      * </p>
 220  
      * Creates a portlet application object based of the WAR file's
 221  
      * WEB-INF/portlet.xml
 222  
      * 
 223  
      * @return @throws
 224  
      *         PortletApplicationException
 225  
      * @throws IOException
 226  
      * @see org.apache.jetspeed.uitl.descriptor.PortletApplicationDescriptor
 227  
      */
 228  
     public MutablePortletApplication createPortletApp(ClassLoader classLoader) throws PortletApplicationException, IOException
 229  
     {
 230  
         Reader portletXmlReader = getReader(PORTLET_XML_PATH);
 231  
         
 232  
         try
 233  
         {
 234  
             PortletApplicationDescriptor paDescriptor = new PortletApplicationDescriptor(portletXmlReader, paName);
 235  
             portletApp = paDescriptor.createPortletApplication(classLoader);
 236  
             // validate(portletApplication);
 237  
             Reader extMetaDataXml = null;
 238  
             try
 239  
             {
 240  
                 extMetaDataXml = getReader(EXTENDED_PORTLET_XML_PATH);
 241  
                 if (extMetaDataXml != null)
 242  
                 {
 243  
                     ExtendedPortletMetadata extMetaData = new ExtendedPortletMetadata(extMetaDataXml, portletApp);
 244  
                     extMetaData.load();
 245  
                 }
 246  
             }
 247  
             catch (IOException e)
 248  
             {
 249  
                 if ( e instanceof FileNotFoundException )
 250  
                 {
 251  
                     log.info("No extended metadata found.");
 252  
                 }
 253  
                 else
 254  
                 {
 255  
                     throw new PortletApplicationException("Failed to load existing metadata.",e);
 256  
                 }
 257  
             }
 258  
             catch (MetaDataException e)
 259  
             {
 260  
                 throw new PortletApplicationException("Failed to load existing metadata.", e);
 261  
             }
 262  
             finally
 263  
             {
 264  
                 if (null != extMetaDataXml)
 265  
                 {
 266  
                     extMetaDataXml.close();
 267  
                 }
 268  
             }
 269  
             portletApp.setChecksum(paChecksum);
 270  
             return portletApp;
 271  
         }
 272  
         finally
 273  
         {
 274  
             if (portletXmlReader != null)
 275  
             {
 276  
                 portletXmlReader.close();
 277  
             }
 278  
         }
 279  
     }
 280  
 
 281  
     public MutablePortletApplication createPortletApp() 
 282  
     throws PortletApplicationException, IOException
 283  
     {
 284  
         return createPortletApp(this.getClass().getClassLoader());
 285  
     }
 286  
     
 287  
     /**
 288  
      * 
 289  
      * <p>
 290  
      * getReader
 291  
      * </p>
 292  
      * Returns a <code>java.io.Reader</code> to a resource within this WAR's
 293  
      * structure.
 294  
      * 
 295  
      * @param path
 296  
      *            realtive to an object within this WAR's file structure
 297  
      * @return java.io.Reader to the file within the WAR
 298  
      * @throws IOException
 299  
      *             if the path does not exist or there was a problem reading the
 300  
      *             WAR.
 301  
      *  
 302  
      */
 303  
     protected Reader getReader( String path ) throws IOException
 304  
     {
 305  
         BufferedInputStream is = new BufferedInputStream(getInputStream(path));
 306  
 
 307  
         String enc = "UTF-8";
 308  
         try
 309  
         {
 310  
             is.mark(MAX_BUFFER_SIZE);
 311  
             byte[] buf = new byte[MAX_BUFFER_SIZE];
 312  
             int size = is.read(buf, 0, MAX_BUFFER_SIZE);
 313  
             if (size > 0)
 314  
             {
 315  
                 String key = "encoding=\"";
 316  
                 String data = new String(buf, 0, size, "US-ASCII");
 317  
                 int lb = data.indexOf("\n");
 318  
                 if (lb > 0)
 319  
                 {
 320  
                     data = data.substring(0, lb);
 321  
                 }
 322  
                 int off = data.indexOf(key);
 323  
                 if (off > 0)
 324  
                 {
 325  
                     enc = data.substring(off + key.length(), data.indexOf('"', off + key.length()));
 326  
                 }
 327  
             }
 328  
         }
 329  
         catch (UnsupportedEncodingException e)
 330  
         {
 331  
             log.warn("Unsupported encoding.", e);
 332  
         }
 333  
         catch (IOException e)
 334  
         {
 335  
             log.warn("Unsupported encoding.", e);
 336  
         }
 337  
 
 338  
         //Reset the bytes read
 339  
         is.reset();
 340  
         return new InputStreamReader(is, enc);
 341  
     }
 342  
 
 343  
     /**
 344  
      * 
 345  
      * <p>
 346  
      * getInputStream
 347  
      * </p>
 348  
      * 
 349  
      * Returns a <code>java.io.InputStream</code> to a resource within this
 350  
      * WAR's structure.
 351  
      * 
 352  
      * @param path
 353  
      *            realtive to an object within this WAR's file structure
 354  
      * @return java.io.InputStream to the file within the WAR
 355  
      * @throws IOException
 356  
      *             if the path does not exist or there was a problem reading the
 357  
      *             WAR.
 358  
      */
 359  
     protected InputStream getInputStream( String path ) throws IOException
 360  
     {
 361  
         File child = new File(warStruct.getRootDirectory(), path);
 362  
         if (child == null || !child.exists())
 363  
         {
 364  
             throw new FileNotFoundException("Unable to locate file or path " + child);
 365  
         }
 366  
 
 367  
         FileInputStream fileInputStream = new FileInputStream(child);
 368  
         openedResources.add(fileInputStream);
 369  
         return fileInputStream;
 370  
     }
 371  
 
 372  
     /**
 373  
      * 
 374  
      * <p>
 375  
      * getOutputStream
 376  
      * </p>
 377  
      * 
 378  
      * Returns a <code>java.io.OutputStream</code> to a resource within this
 379  
      * WAR's structure.
 380  
      * 
 381  
      * @param path
 382  
      *            realtive to an object within this WAR's file structure
 383  
      * @return java.io.Reader to the file within the WAR
 384  
      * @throws IOException
 385  
      *             if the path does not exist or there was a problem reading the
 386  
      *             WAR.
 387  
      */
 388  
     protected OutputStream getOutputStream( String path ) throws IOException
 389  
     {
 390  
         File child = new File(warStruct.getRootDirectory(), path);
 391  
         if (child == null)             
 392  
         {
 393  
             throw new FileNotFoundException("Unable to locate file or path " + child);
 394  
         }
 395  
         FileOutputStream fileOutputStream = new FileOutputStream(child);
 396  
         openedResources.add(fileOutputStream);
 397  
         return fileOutputStream;
 398  
     }
 399  
 
 400  
     protected Writer getWriter( String path ) throws IOException
 401  
     {
 402  
         return new OutputStreamWriter(getOutputStream(path));
 403  
     }
 404  
 
 405  
     /**
 406  
      * 
 407  
      * <p>
 408  
      * copyWar
 409  
      * </p>
 410  
      * Copies the entire WAR structure to the path defined in
 411  
      * <code>targetAppRoot</code>
 412  
      * 
 413  
      * @param targetAppRoot
 414  
      *            target to copy this WAR's content to. If the path ends in
 415  
      *            <code>.war</code> or <code>.jar</code>. The war will be
 416  
      *            copied into that file in jar format.
 417  
      * @return PortletApplicationWar representing the newly created WAR.
 418  
      * @throws IOException
 419  
      */
 420  
     public PortletApplicationWar copyWar( String targetAppRoot ) throws IOException
 421  
     {
 422  
         // FileObject target = fsManager.resolveFile(new
 423  
         // File(targetAppRoot).getAbsolutePath());
 424  
         FileSystemHelper target = new DirectoryHelper(class="keyword">new File(targetAppRoot));
 425  
         try
 426  
         {
 427  
             target.copyFrom(warStruct.getRootDirectory());
 428  
 
 429  
             return new PortletApplicationWar(target, paName, webAppContextRoot, paChecksum);
 430  
 
 431  
         }
 432  
         catch (IOException e)
 433  
         {
 434  
             throw e;
 435  
         }
 436  
         finally
 437  
         {
 438  
             target.close();
 439  
 
 440  
         }
 441  
     }
 442  
 
 443  
     /**
 444  
      * 
 445  
      * <p>
 446  
      * removeWar
 447  
      * </p>
 448  
      * Deletes this WAR. If the WAR is a file structure and not an actual WAR
 449  
      * file, all children are delted first, then the directory is removed.
 450  
      * 
 451  
      * @throws IOException
 452  
      *             if there is an error removing the WAR from the file system.
 453  
      */
 454  
     public void removeWar() throws IOException
 455  
     {
 456  
         if (warStruct.getRootDirectory().exists())
 457  
         {
 458  
             warStruct.remove();
 459  
         }
 460  
         else
 461  
         {
 462  
             throw new FileNotFoundException("PortletApplicationWar ," + warStruct.getRootDirectory()
 463  
                     + ", does not exist.");
 464  
         }
 465  
     }
 466  
 
 467  
     /**
 468  
      * Validate a PortletApplicationDefinition tree AFTER its
 469  
      * WebApplicationDefinition has been loaded. Currently, only the security
 470  
      * role references of the portlet definitions are validated:
 471  
      * <ul>
 472  
      * <li>A security role reference should reference a security role through a
 473  
      * roleLink. A warning message is logged if a direct reference is used.
 474  
      * <li>For a security role reference a security role must be defined in the
 475  
      * web application. An error message is logged and a
 476  
      * PortletApplicationException is thrown if not.
 477  
      * </ul>
 478  
      * 
 479  
      * @throws PortletApplicationException
 480  
      */
 481  
     public void validate() throws PortletApplicationException
 482  
     {
 483  
         if (portletApp == null || webApp == class="keyword">null)
 484  
         {
 485  
             throw new IllegalStateException(
 486  
                     "createWebApp() and createPortletApp() must be called before invoking validate()");
 487  
         }
 488  
 
 489  
         SecurityRoleSet roles = webApp.getSecurityRoles();
 490  
         Collection portlets = portletApp.getPortletDefinitions();
 491  
         Iterator portletIterator = portlets.iterator();
 492  
         while (portletIterator.hasNext())
 493  
         {
 494  
             PortletDefinition portlet = (PortletDefinition) portletIterator.next();
 495  
             SecurityRoleRefSet securityRoleRefs = portlet.getInitSecurityRoleRefSet();
 496  
             Iterator roleRefsIterator = securityRoleRefs.iterator();
 497  
             while (roleRefsIterator.hasNext())
 498  
             {
 499  
                 SecurityRoleRef roleRef = (SecurityRoleRef) roleRefsIterator.next();
 500  
                 String roleName = roleRef.getRoleLink();
 501  
                 if (roleName == null || roleName.length() == 0)
 502  
                 {
 503  
                     roleName = roleRef.getRoleName();
 504  
                 }
 505  
                 if (roles.get(roleName) == null)
 506  
                 {
 507  
                     String errorMsg = "Undefined security role " + roleName + " referenced from portlet "
 508  
                             + portlet.getName();
 509  
                     throw new PortletApplicationException(errorMsg);
 510  
                 }
 511  
             }
 512  
         }
 513  
     }
 514  
 
 515  
     /**
 516  
      * 
 517  
      * <p>
 518  
      * processWebXML
 519  
      * </p>
 520  
      * 
 521  
      * Infuses this PortletApplicationWar's web.xml file with
 522  
      * <code>servlet</code> and a <code>servlet-mapping</code> element for
 523  
      * the JetspeedContainer servlet. This is only done if the descriptor does
 524  
      * not already contain these items.
 525  
      * 
 526  
      * @throws MetaDataException
 527  
      *             if there is a problem infusing
 528  
      */
 529  
     public void processWebXML() throws MetaDataException
 530  
     {
 531  
         SAXBuilder builder = new SAXBuilder();
 532  
         Writer webXmlWriter = null;
 533  
         InputStream webXmlIn = null;
 534  
 
 535  
         try
 536  
         {
 537  
             // Use the local dtd instead of remote dtd. This
 538  
             // allows to deploy the application offline
 539  
             builder.setEntityResolver(new EntityResolver()
 540  
             {
 541  0
                 public InputSource resolveEntity( java.lang.String class="keyword">publicId, java.lang.String systemId )
 542  
                         throws SAXException, java.io.IOException
 543  
                 {
 544  
 
 545  0
                     if (systemId.equals("http://java.sun.com/dtd/web-app_2_3.dtd"))
 546  
                     {
 547  0
                         return new InputSource(getClass().getResourceAsStream("web-app_2_3.dtd"));
 548  
                     }
 549  0
                     else return null;
 550  
                 }
 551  
             });
 552  
 
 553  
             Document doc = null;
 554  
             
 555  
             try
 556  
             {
 557  
                 webXmlIn = getInputStream(WEB_XML_PATH);
 558  
                 doc = builder.build(webXmlIn);
 559  
             }
 560  
             catch (FileNotFoundException fnfe)
 561  
             {
 562  
                 // web.xml does not exist, create it
 563  
                 File file = File.createTempFile("j2-temp-", ".xml");
 564  
                 FileWriter writer = new FileWriter(file);
 565  
                 writer.write(WEB_XML_STRING);
 566  
                 writer.close();
 567  
                 doc = builder.build(file);
 568  
                 file.delete();
 569  
             }
 570  
             
 571  
             
 572  
             if (webXmlIn != null)
 573  
             {
 574  
                 webXmlIn.close();
 575  
             }
 576  
 
 577  
             JetspeedWebApplicationRewriterFactory rewriterFactory = new JetspeedWebApplicationRewriterFactory();
 578  
             JetspeedWebApplicationRewriter rewriter = rewriterFactory.getInstance(doc);
 579  
             rewriter.processWebXML();
 580  
             
 581  
             if (rewriter.isChanged())
 582  
             {
 583  
                 System.out.println("Writing out infused web.xml for " + paName);
 584  
                 XMLOutputter output = new XMLOutputter(Format.getPrettyFormat());
 585  
                 webXmlWriter = getWriter(WEB_XML_PATH);
 586  
                 output.output(doc, webXmlWriter);
 587  
                 webXmlWriter.flush();
 588  
 
 589  
             }
 590  
             
 591  
             if(rewriter.isPortletTaglibAdded())
 592  
             {
 593  
                 //add portlet tag lib to war
 594  
                 String path = Jetspeed.getRealPath("WEB-INF/tld");
 595  
                 if (path != null)
 596  
                 {
 597  
                     File portletTaglibDir = new File(path);
 598  
                     File child = new File(warStruct.getRootDirectory(), "WEB-INF/tld");
 599  
                     DirectoryHelper dh = new DirectoryHelper(child);
 600  
                     dh.copyFrom(portletTaglibDir, new FileFilter(){
 601  
 
 602  
                         public boolean accept(File pathname)
 603  
                         {
 604  
                             return pathname.getName().indexOf("portlet.tld") != -1;
 605  
                         }                    
 606  
                     });                
 607  
                     dh.close();
 608  
                 }
 609  
             }
 610  
 
 611  
         }
 612  
         catch (Exception e)
 613  
         {
 614  
             e.printStackTrace();
 615  
             throw new MetaDataException("Unable to process web.xml for infusion " + e.toString(), e);
 616  
         }
 617  
         finally
 618  
         {
 619  
             if (webXmlWriter != null)
 620  
             {
 621  
                 try
 622  
                 {
 623  
                     webXmlWriter.close();
 624  
                 }
 625  
                 catch (IOException e1)
 626  
                 {
 627  
 
 628  
                 }
 629  
             }
 630  
 
 631  
             if (webXmlIn != null)
 632  
             {
 633  
                 try
 634  
                 {
 635  
                     webXmlIn.close();
 636  
                 }
 637  
                 catch (IOException e1)
 638  
                 {
 639  
 
 640  
                 }
 641  
             }
 642  
         }
 643  
 
 644  
     }
 645  
 
 646  
 
 647  
     /**
 648  
      * 
 649  
      * <p>
 650  
      * close
 651  
      * </p>
 652  
      * Closes any resource this PortletApplicationWar may have opened.
 653  
      * 
 654  
      * @throws IOException
 655  
      */
 656  
     public void close() throws IOException
 657  
     {
 658  
 
 659  
         Iterator resources = openedResources.iterator();
 660  
         while (resources.hasNext())
 661  
         {
 662  
             try
 663  
             {
 664  
                 Object res = resources.next();
 665  
                 if (res instanceof InputStream)
 666  
                 {
 667  
                     ((InputStream) res).close();
 668  
                 }
 669  
                 else if (res instanceof OutputStream)
 670  
                 {
 671  
                     ((OutputStream) res).close();
 672  
                 }
 673  
             }
 674  
             catch (Exception e)
 675  
             {
 676  
 
 677  
             }
 678  
         }
 679  
 
 680  
     }
 681  
 
 682  
     /**
 683  
      * 
 684  
      * <p>
 685  
      * createClassloader
 686  
      * </p>
 687  
      * 
 688  
      * Use this method to create a classloader based on this wars structure.
 689  
      * I.e. it will create a ClassLoader containing the contents of
 690  
      * WEB-INF/classes and WEB-INF/lib and the ClassLoader will be searched in
 691  
      * that order.
 692  
      * 
 693  
      * 
 694  
      * @param parent
 695  
      *            Parent ClassLoader. Can be <code>null</code>
 696  
      * @return @throws
 697  
      *         IOException
 698  
      */
 699  
     public ClassLoader createClassloader( ClassLoader parent ) throws IOException
 700  
     {
 701  
         ArrayList urls = new ArrayList();
 702  
         File webInfClasses = null;
 703  
 
 704  
         webInfClasses = new File(warStruct.getRootDirectory(), ("WEB-INF/classes/"));
 705  
         if (webInfClasses.exists())
 706  
         {
 707  
             log.info("Adding " + webInfClasses.toURL() + " to class path.");
 708  
             urls.add(webInfClasses.toURL());
 709  
         }
 710  
 
 711  
         File webInfLib = new File(warStruct.getRootDirectory(), "WEB-INF/lib");
 712  
 
 713  
         if (webInfLib.exists())
 714  
         {
 715  
             File[] jars = webInfLib.listFiles();
 716  
 
 717  
             for (int i = 0; i < jars.length; i++)
 718  
             {
 719  
                 File jar = jars[i];
 720  
                 log.info("Adding " + jar.toURL() + " to class path.");
 721  
                 urls.add(jar.toURL());
 722  
             }
 723  
         }
 724  
 
 725  
         return new URLClassLoader((URL[]) urls.toArray(class="keyword">new URL[urls.size()]), parent);
 726  
     }
 727  
 
 728  
     /**
 729  
      * @return Returns the paName.
 730  
      */
 731  
     public String getPortletApplicationName()
 732  
     {
 733  
         return paName;
 734  
     }
 735  
 
 736  
     /**
 737  
      * 
 738  
      * <p>
 739  
      * getDeployedPath
 740  
      * </p>
 741  
      * 
 742  
      * @return A string representing the path to this WAR in the form of a URL
 743  
      *         or <code>null</code> is the URL could not be created.
 744  
      */
 745  
     public String getDeployedPath()
 746  
     {
 747  
         try
 748  
         {
 749  
             return warStruct.getRootDirectory().toURL().toExternalForm();
 750  
         }
 751  
         catch (MalformedURLException e)
 752  
         {
 753  
             return null;
 754  
         }
 755  
     }
 756  
     
 757  
     public FileSystemHelper getFileSystem()
 758  
     {
 759  
         return warStruct;
 760  
     }
 761  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.