/** * 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.portal.remote.axis.extender.internal; import com.liferay.osgi.util.BundleUtil; import com.liferay.portal.kernel.bean.ClassLoaderBeanHandler; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.util.AggregateClassLoader; import com.liferay.portal.kernel.util.ProxyUtil; import com.liferay.portal.servlet.filters.authverifier.AuthVerifierFilter; import com.liferay.util.axis.AxisServlet; import java.net.URL; import java.util.Dictionary; import java.util.Enumeration; import java.util.Hashtable; import javax.servlet.Filter; import javax.servlet.Servlet; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleEvent; import org.osgi.framework.ServiceRegistration; import org.osgi.framework.wiring.BundleWiring; import org.osgi.service.component.ComponentContext; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Deactivate; import org.osgi.service.http.context.ServletContextHelper; import org.osgi.service.http.whiteboard.HttpWhiteboardConstants; import org.osgi.util.tracker.BundleTracker; import org.osgi.util.tracker.BundleTrackerCustomizer; /** * @author Carlos Sierra Andrés */ @Component(immediate = true) public class AxisExtender { @Activate protected void activate(ComponentContext componentContext) { _bundleContext = componentContext.getBundleContext(); _bundleTracker = new BundleTracker<>( _bundleContext, Bundle.ACTIVE, new BundleRegistrationInfoBundleTrackerCustomizer()); _bundleTracker.open(); } @Deactivate protected void deactivate() { _bundleTracker.close(); } private static final Log _log = LogFactoryUtil.getLog(AxisExtender.class); private BundleContext _bundleContext; private BundleTracker<BundleRegistrationInfo> _bundleTracker; private static class BundleRegistrationInfo { public BundleRegistrationInfo( ServiceRegistration<Filter> authVerifierFilterServiceRegistration, ServiceRegistration<Servlet> axisServletServiceRegistration, ServiceRegistration<ServletContextHelper> bundleServletContextServiceRegistration) { _authVerifierFilterServiceRegistration = authVerifierFilterServiceRegistration; _axisServletServiceRegistration = axisServletServiceRegistration; _bundleServletContextHelperServiceRegistration = bundleServletContextServiceRegistration; } public ServiceRegistration<Filter> getAuthVerifierFilterServiceRegistration() { return _authVerifierFilterServiceRegistration; } public ServiceRegistration<Servlet> getAxisServletServiceRegistration() { return _axisServletServiceRegistration; } public ServiceRegistration<ServletContextHelper> getBundleServletContextHelperServiceRegistration() { return _bundleServletContextHelperServiceRegistration; } private final ServiceRegistration<Filter> _authVerifierFilterServiceRegistration; private final ServiceRegistration<Servlet> _axisServletServiceRegistration; private final ServiceRegistration<ServletContextHelper> _bundleServletContextHelperServiceRegistration; } private class BundleRegistrationInfoBundleTrackerCustomizer implements BundleTrackerCustomizer<BundleRegistrationInfo> { @Override public BundleRegistrationInfo addingBundle( final Bundle bundle, BundleEvent bundleEvent) { Enumeration<URL> enumeration = bundle.findEntries( "/WEB-INF", "server-config.wsdd", false); if ((enumeration == null) || !enumeration.hasMoreElements()) { return null; } Dictionary<String, Object> properties = new Hashtable<>(); properties.put( HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, "liferay.axis." + bundle.getSymbolicName()); properties.put( HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, "/" + bundle.getSymbolicName()); ServiceRegistration<ServletContextHelper> bundleServletContextHelperServiceRegistration = _bundleContext.registerService( ServletContextHelper.class, new ServletContextHelper(bundle) { @Override public URL getResource(String name) { if (name.startsWith("/")) { name = name.substring(1); } return BundleUtil.getResourceInBundleOrFragments( bundle, name); } }, properties); properties = new Hashtable<>(); properties.put( HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, "liferay.axis." + bundle.getSymbolicName()); properties.put( HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_NAME, AuthVerifierFilter.class.getName()); properties.put( HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_PATTERN, "/api/axis/*"); ServiceRegistration<Filter> authVerifierFilterServiceRegistration = _bundleContext.registerService( Filter.class, new AuthVerifierFilter(), properties); properties = new Hashtable<>(); properties.put( HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, "liferay.axis." + bundle.getSymbolicName()); properties.put( HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, AxisServlet.class.getName()); properties.put( HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/api/axis/*"); properties.put("servlet.init.axis.servicesPath", "/api/axis/"); properties.put("servlet.init.httpMethods", "GET,POST,HEAD"); Bundle bundleContextBundle = _bundleContext.getBundle(); BundleWiring bundleContextBundleBundleWiring = bundleContextBundle.adapt(BundleWiring.class); AggregateClassLoader aggregateClassLoader = new AggregateClassLoader( bundleContextBundleBundleWiring.getClassLoader()); BundleWiring bundleWiring = bundle.adapt(BundleWiring.class); aggregateClassLoader.addClassLoader(bundleWiring.getClassLoader()); Servlet servlet = (Servlet)ProxyUtil.newProxyInstance( aggregateClassLoader, new Class<?>[] {Servlet.class}, new ClassLoaderBeanHandler( new AxisServlet(), aggregateClassLoader)); ServiceRegistration<Servlet> axisServletServiceRegistration = _bundleContext.registerService( Servlet.class, servlet, properties); return new BundleRegistrationInfo( authVerifierFilterServiceRegistration, axisServletServiceRegistration, bundleServletContextHelperServiceRegistration); } @Override public void modifiedBundle( Bundle bundle, BundleEvent bundleEvent, BundleRegistrationInfo bundleRegistrationInfo) { removedBundle(bundle, bundleEvent, bundleRegistrationInfo); addingBundle(bundle, bundleEvent); } @Override public void removedBundle( Bundle bundle, BundleEvent bundleEvent, BundleRegistrationInfo bundleRegistrationInfo) { ServiceRegistration<Servlet> axisServletServiceRegistration = bundleRegistrationInfo.getAxisServletServiceRegistration(); try { axisServletServiceRegistration.unregister(); } catch (Exception e) { _log.error(e, e); } ServiceRegistration<Filter> authVerifierFilterServiceRegistration = bundleRegistrationInfo. getAuthVerifierFilterServiceRegistration(); try { authVerifierFilterServiceRegistration.unregister(); } catch (Exception e) { _log.error(e, e); } ServiceRegistration<ServletContextHelper> bundleServletContextHelperServiceRegistration = bundleRegistrationInfo. getBundleServletContextHelperServiceRegistration(); try { bundleServletContextHelperServiceRegistration.unregister(); } catch (Exception e) { _log.error(e, e); } } } }