/******************************************************************************* * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * 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 (at your option) * 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. * *******************************************************************************/ package com.liferay.ide.server.core.portal; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.URL; import java.util.Set; import java.util.jar.JarInputStream; import javax.management.MBeanServerConnection; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; import org.osgi.framework.dto.BundleDTO; /** * @author Gregory Amerson */ public class BundleDeployer extends JMXBundleDeployer { private final static String OBJECTNAME = "osgi.core"; public BundleDeployer( int jmxRemotePort ) { super( jmxRemotePort ); } /** * Gets the current list of installed bsns, compares it to the bsn provided. * If bsn doesn't exist, then install it. If it does exist then update it. * * @param bsn * Bundle-SymbolicName of bundle you are wanting to deploy * @param bundle * the bundle * @return the id of the updated or installed bundle * @throws Exception */ public long deploy(String bsn, String bundleUrl) throws Exception { MBeanServerConnection connection = mBeanServerConnection; final ObjectName framework = getFramework(connection); long bundleId = -1; for (BundleDTO osgiBundle : listBundles()) { if (osgiBundle.symbolicName.equals(bsn)) { bundleId = osgiBundle.id; break; } } boolean isFragment = false; if( !bundleUrl.contains( "webbundle:" ) ) { final File bundleFile = new File( new URL( bundleUrl ).toURI() ); try ( JarInputStream jarStream = new JarInputStream( new FileInputStream( bundleFile ) ) ) { isFragment = jarStream.getManifest().getMainAttributes().getValue( "Fragment-Host" ) != null; } catch( Exception e ) { } } // TODO serve bundle url over http so it works for non file:// urls if (bundleId > -1) { if (!isFragment) { connection.invoke(framework, "stopBundle", new Object[] { bundleId }, new String[] { "long" }); } connection.invoke(framework, "updateBundleFromURL", new Object[] { bundleId, bundleUrl }, new String[] { "long", String.class.getName() }); connection.invoke(framework, "refreshBundle", new Object[] { bundleId }, new String[] { "long" }); } else { Object installed = connection.invoke( framework, "installBundleFromURL", new Object[] { bundleUrl, bundleUrl }, new String[] { String.class.getName(), String.class.getName() }); bundleId = Long.parseLong(installed.toString()); } if( !isFragment ) { connection.invoke(framework, "startBundle", new Object[] { bundleId }, new String[] { "long" }); } return bundleId; } private static ObjectName getFramework( MBeanServerConnection mBeanServerConnection ) throws MalformedObjectNameException, IOException { final ObjectName objectName = new ObjectName( OBJECTNAME + ":type=framework,*" ); final Set<ObjectName> objectNames = mBeanServerConnection.queryNames( objectName, null ); if( objectNames != null && objectNames.size() > 0 ) { return objectNames.iterator().next(); } return null; } public boolean ping() { try { return mBeanServerConnection != null && mBeanServerConnection.queryNames( new ObjectName( "osgi.core:type=bundleState,*" ), null ) != null; } catch( Exception e ) { return false; } } }