/**
* EasyBeans
* Copyright (C) 2012 Bull S.A.S.
* Contact: easybeans@ow2.org
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
* --------------------------------------------------------------------------
* $Id$
* --------------------------------------------------------------------------
*/
package org.ow2.easybeans.ejbinwar;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.ow2.util.archive.api.ArchiveException;
import org.ow2.util.archive.api.IArchive;
import org.ow2.util.archive.impl.AbsArchiveImpl;
import org.ow2.util.archive.impl.ArchiveManager;
import org.ow2.util.url.URLUtils;
/**
* Wrap a War archive into a EJB Archive.
* @author Florent Benoit
*/
public class EJBInWarArchive extends AbsArchiveImpl implements IArchive {
/**
* WEB-INF entry.
*/
private static final String WEB_INF = "WEB-INF/";
/**
* WEB-INF/ejb-jar.xml.
*/
private static final String WEB_INF_EJBJAR_XML = WEB_INF.concat("ejb-jar.xml");
/**
* WEB-INF/easybeans.xml.
*/
private static final String WEB_INF_EASYBEANS_XML = WEB_INF.concat("easybeans.xml");
/**
* META-INF/ejb-jar.xml.
*/
public static final String META_INF_EJBJAR_XML = "META-INF/ejb-jar.xml";
/**
* META-INF/easybeans.xml.
*/
public static final String META_INF_EASYBEANS_XML = "META-INF/easybeans.xml";
/**
* WEB-INF/classes folder.
*/
private static final String WEB_INF_CLASSES = WEB_INF.concat("classes");
/**
* WEB-INF/lib folder.
*/
private static final String WEB_INF_LIB = WEB_INF.concat("lib");
/**
* .jar Suffix.
*/
private static final String JAR_SUFFIX = ".jar";
/**
* .class Suffix.
*/
private static final String CLASS_SUFFIX = ".class";
/**
* Wrapped Archive.
*/
private IArchive wrappedWarArchive = null;
/**
* Resource names of the entries.
*/
private Map<String, URL> entries = null;
/**
* Build a new EJB archive based on the given WAR archive.
* @param wrappedWarArchive the archive to wrap
* @throws ArchiveException if archive can't be transformed
*/
public EJBInWarArchive(final IArchive wrappedWarArchive) throws ArchiveException {
super();
this.wrappedWarArchive = wrappedWarArchive;
this.entries = new HashMap<String, URL>();
init();
}
/**
* Initialize the archive.
* @throws ArchiveException if entries can't be read
*/
public void init() throws ArchiveException {
// Init entries
Iterator<String> itEntries = this.wrappedWarArchive.getEntries();
while (itEntries.hasNext()) {
String wrappedEntry = itEntries.next();
// Handle special case of ejb-jar.xml and easybeans.xml
if (WEB_INF_EJBJAR_XML.equals(wrappedEntry)) {
// add it on our own entry
addEntry(META_INF_EJBJAR_XML, this.wrappedWarArchive.getResource(wrappedEntry));
}
if (WEB_INF_EASYBEANS_XML.equals(wrappedEntry)) {
// add it on our own entry
addEntry(META_INF_EASYBEANS_XML, this.wrappedWarArchive.getResource(wrappedEntry));
}
if (META_INF_EASYBEANS_XML.equals(wrappedEntry)) {
// add it on our own entry
addEntry(META_INF_EASYBEANS_XML, this.wrappedWarArchive.getResource(wrappedEntry));
}
// Filter WEB-INF/ resources
if (wrappedEntry.startsWith(WEB_INF)) {
// remove WEB-INF/classes
if (wrappedEntry.startsWith(WEB_INF_CLASSES)) {
addEntry(wrappedEntry.substring(WEB_INF_CLASSES.length() + 1), this.wrappedWarArchive
.getResource(wrappedEntry));
}
// WEB-INF/lib
if (wrappedEntry.startsWith(WEB_INF_LIB) && wrappedEntry.endsWith(JAR_SUFFIX)) {
// Get all entries of this jar
URL url = this.wrappedWarArchive.getResource(wrappedEntry);
// Now, scan all entries (if available)
if ("file".equals(url.getProtocol())) {
File lib = URLUtils.urlToFile(url);
IArchive libArchive = ArchiveManager.getInstance().getArchive(lib);
Iterator<String> libIterator = libArchive.getEntries();
while (libIterator.hasNext()) {
String libEntry = libIterator.next();
if (libEntry.endsWith(CLASS_SUFFIX)) {
addEntry(libEntry, libArchive.getResource(libEntry));
}
}
}
}
}
}
}
/**
* Add the given resource name on this archive which is acting as the delegating entry.
* @param name the resource name
* @param wrappedEntry the entry to wrap
* @throws ArchiveException if entry can't be added
*/
protected void addEntry(final String name, final URL wrappedEntry) throws ArchiveException {
// Add the resource name
this.entries.put(name, wrappedEntry);
}
/**
* Close the underlying Resource.
* @return Returns <code>true</code> if the close was succesful,
* <code>false</code> otherwise.
*/
public boolean close() {
return this.wrappedWarArchive.close();
}
/**
* @return Returns all resources name in the archive.
* @throws ArchiveException if method fails.
*/
public Iterator<String> getEntries() throws ArchiveException {
// Return our own filtered entries
return this.entries.keySet().iterator();
}
/**
* @return a description of this archive. This name could be used in logger
* info.
*/
public String getName() {
// Prefix the name
return "EJBInWar[".concat(this.wrappedWarArchive.getName()).concat("]");
}
/**
* @param resourceName The resource name to be looked up.
* @return Returns the resource URL if the resource has been found. null
* otherwise.
* @throws ArchiveException if method fails.
*/
public URL getResource(final String resourceName) throws ArchiveException {
return this.entries.get(resourceName);
}
/**
* @return Returns an Iterator of Resource's URL.
* @throws ArchiveException if method fails.
*/
public Iterator<URL> getResources() throws ArchiveException {
return this.entries.values().iterator();
}
/**
* @param resourceName The resource name to be looked up.
* @return Returns an Iterator of matching resources.
* @throws ArchiveException if method fails.
*/
public Iterator<URL> getResources(final String resourceName) throws ArchiveException {
List<URL> lst = new ArrayList<URL>();
URL url = this.entries.get(resourceName);
if (url != null) {
lst.add(url);
}
return lst.iterator();
}
/**
* Returns an URL that can be used to access the resource described by this
* IArchive. This URL MUST be canonicalized (at least when this is a file)
* because it is often used as a key.
* @return Returns the resource URL.
* @throws ArchiveException if method fails.
*/
public URL getURL() throws ArchiveException {
return this.wrappedWarArchive.getURL();
}
/**
*
* @return Returns the original wrapped archive
*/
public IArchive getWrappedWarArchive() {
return wrappedWarArchive;
}
}