Index: OSGiArchiveHandler.java =================================================================== --- OSGiArchiveHandler.java (revision 56101) +++ OSGiArchiveHandler.java (working copy) @@ -41,34 +41,35 @@ package org.glassfish.extras.osgicontainer; import org.glassfish.api.deployment.archive.*; +import org.glassfish.api.deployment.DeployCommandParameters; import org.glassfish.api.deployment.DeploymentContext; import org.glassfish.internal.deployment.GenericHandler; -import org.glassfish.internal.api.DelegatingClassLoader; import org.jvnet.hk2.annotations.Service; -import org.glassfish.hk2.api.PreDestroy; +import com.sun.enterprise.util.io.FileUtils; + import javax.inject.Singleton; +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.File; +import java.io.InputStream; +import java.io.OutputStream; import java.util.jar.Manifest; +import java.util.jar.JarFile; +import java.util.jar.JarInputStream; import java.util.*; import java.net.URL; -import java.net.URI; -import java.lang.ref.WeakReference; +import java.net.URLConnection; -import com.sun.enterprise.module.ModulesRegistry; -import com.sun.enterprise.module.Module; -import com.sun.enterprise.module.ModuleDefinition; -import com.sun.enterprise.module.common_impl.DefaultModuleDefinition; -import com.sun.enterprise.util.io.FileUtils; - import javax.inject.Inject; /** * Archive Handler for OSGi modules. * * @author Jerome Dochez + * @author TangYong(tangyong@cn.fujitsu.com) */ @Service(name=OSGiArchiveDetector.OSGI_ARCHIVE_TYPE) @Singleton @@ -103,4 +104,127 @@ return getDefaultApplicationNameFromArchiveName(archive); } + /** + * Overriding the expand method of base class(GenericHandler) in order to + * support allowing wrapping of non-OSGi bundles when --type=osgi option is + * used in deploy command or GUI. Pl. see [GLASSFISH-16651] + * + * @param source + * of the expanding + * @param target + * of the expanding + * @param context + * deployment context + * @throws IOException + * when the archive is corrupted + */ + @Override + public void expand(ReadableArchive source, WritableArchive target, + DeploymentContext context) throws IOException { + Properties props = context + .getCommandParameters(DeployCommandParameters.class).properties; + if ((props != null) && (props.containsKey("uriScheme"))) { + + // see [GLASSFISH-16651] + // if uriScheme is webbundle, we need to construct a new URL based on user's input + // and souce parameter and call openConnection() and getInputStream() on it. + // user's input can be the following: + // asadmin deploy --properties uriScheme=webBundle:Bundle-SymbolicName=foo: + // Import-Package=javax.servlet:Web-ContextPath=/foo /tmp/foo.war + Enumeration p = props.propertyNames(); + StringBuilder sb = new StringBuilder(); + + sb.append(props.getProperty("uriScheme")); + sb.append(":"); + sb.append(context.getOriginalSource().getURI().toURL() + .toExternalForm() + + "?"); + + while (p.hasMoreElements()) { + String key = (String) p.nextElement(); + if ("uriScheme".equalsIgnoreCase(key)) { + continue; + } + sb.append(key); + sb.append("="); + sb.append(props.getProperty(key)); + sb.append("&"); + } + + String urlStr = sb.toString(); + if (urlStr.charAt(urlStr.length() - 1) == '&') { + urlStr = urlStr.substring(0, urlStr.length() - 1); + } + + URL url = new URL(urlStr); + URLConnection conn = null; + InputStream is = null; + int BUFSIZE = 4096; + ByteArrayOutputStream baos = new ByteArrayOutputStream(BUFSIZE); + JarInputStream jis = null; + + try { + conn = url.openConnection(); + is = conn.getInputStream(); + copyStreamToFile(is, baos, BUFSIZE); + jis = new JarInputStream(new ByteArrayInputStream( + baos.toByteArray())); + + Enumeration e = source.entries(); + while (e.hasMoreElements()) { + String entryName = e.nextElement(); + InputStream bis = new BufferedInputStream( + source.getEntry(entryName)); + OutputStream os = null; + try { + os = target.putNextEntry(entryName); + FileUtils.copy(bis, os, source.getEntrySize(entryName)); + } finally { + if (os != null) { + target.closeEntry(); + } + bis.close(); + } + } + + //Add MANIFEST File To Target and Write the MANIFEST File To Target + Manifest m = null; + m = jis.getManifest(); + if (m != null) { + OutputStream os = null; + try { + os = target.putNextEntry(JarFile.MANIFEST_NAME); + m.write(os); + } finally { + if (os != null) { + target.closeEntry(); + } + } + } + } finally { + if (is != null) + is.close(); + if (baos != null) + baos.close(); + if (jis != null) + jis.close(); + } + } else { + super.expand(source, target, context); + } + } + + private void copyStreamToFile(InputStream is, OutputStream os, int bufsize) + throws IOException { + try { + byte[] b = new byte[bufsize]; + int len = 0; + while ((len = is.read(b)) != -1) { + os.write(b, 0, len); + } + } finally { + if (is != null) + is.close(); + } + } }