/* * JBoss, Home of Professional Open Source. * Copyright 2010, Red Hat, Inc., and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This 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 software 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 software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.as.osgi.deployment; import static org.jboss.as.osgi.OSGiLogger.LOGGER; import static org.jboss.as.osgi.service.ModuleRegistrationTracker.MODULE_REGISTRATION_COMPLETE; import java.util.List; import org.jboss.as.osgi.OSGiConstants; import org.jboss.as.osgi.service.FrameworkActivator; import org.jboss.as.osgi.service.InitialDeploymentTracker; import org.jboss.as.server.deployment.AttachmentKey; import org.jboss.as.server.deployment.Attachments; import org.jboss.as.server.deployment.DeploymentPhaseContext; import org.jboss.as.server.deployment.DeploymentUnit; import org.jboss.as.server.deployment.DeploymentUnitProcessingException; import org.jboss.as.server.deployment.DeploymentUnitProcessor; import org.jboss.as.server.deployment.annotation.CompositeIndex; import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.AnnotationTarget; import org.jboss.jandex.ClassInfo; import org.jboss.jandex.DotName; import org.jboss.jandex.FieldInfo; import org.jboss.jandex.MethodInfo; import org.jboss.jandex.MethodParameterInfo; import org.jboss.jandex.Type; import org.jboss.osgi.deployment.deployer.Deployment; import org.jboss.osgi.framework.Services; /** * Activates the OSGi subsystem if an OSGi deployment is detected. * * @author Thomas.Diesler@jboss.com * @since 20-Jun-2012 */ public class FrameworkActivateProcessor implements DeploymentUnitProcessor { private final InitialDeploymentTracker deploymentTracker; public FrameworkActivateProcessor(InitialDeploymentTracker deploymentTracker) { this.deploymentTracker = deploymentTracker; } @Override public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException { // Check whether this is an OSGi deployment or whether it wants to have an OSGi type injected DeploymentUnit depUnit = phaseContext.getDeploymentUnit(); Deployment deployment = depUnit.getAttachment(OSGiConstants.DEPLOYMENT_KEY); boolean hasInjectionPoint = hasValidInjectionPoint(depUnit); if (deployment == null && hasInjectionPoint == false) return; // Activate the framework if not done so already FrameworkActivator.activate(depUnit.getAttachment(Attachments.SERVICE_VERIFICATION_HANDLER)); // Setup a dependency on the the next phase. Persistent bundles have a dependency on the bootstrap bundles if (deploymentTracker.isComplete()) { phaseContext.addDeploymentDependency(Services.FRAMEWORK_ACTIVE, AttachmentKey.create(Object.class)); } else { phaseContext.addDeploymentDependency(MODULE_REGISTRATION_COMPLETE, AttachmentKey.create(Object.class)); } // Make these services available for a bundle deployment only phaseContext.addDeploymentDependency(Services.FRAMEWORK_CREATE, OSGiConstants.SYSTEM_CONTEXT_KEY); phaseContext.addDeploymentDependency(Services.BUNDLE_MANAGER, OSGiConstants.BUNDLE_MANAGER_KEY); phaseContext.addDeploymentDependency(Services.RESOLVER, OSGiConstants.RESOLVER_KEY); phaseContext.addDeploymentDependency(Services.ENVIRONMENT, OSGiConstants.ENVIRONMENT_KEY); } @Override public void undeploy(final DeploymentUnit depUnit) { } private boolean hasValidInjectionPoint(DeploymentUnit depUnit) { return hasInjectionPoint(depUnit, "javax.inject.Inject") || hasInjectionPoint(depUnit, "javax.annotation.Resource"); } private boolean isInjectingOsgi(String typeName) { return typeName.startsWith("org.osgi.framework") || typeName.startsWith("org.osgi.service"); } // Check for injection target fields of type org.osgi.framework.* private boolean hasInjectionPoint(DeploymentUnit depUnit, String anName) { boolean result = false; CompositeIndex compositeIndex = depUnit.getAttachment(Attachments.COMPOSITE_ANNOTATION_INDEX); List<AnnotationInstance> annotationList = compositeIndex.getAnnotations(DotName.createSimple(anName)); String typeName = null; ClassInfo declaringClass = null; try { for (AnnotationInstance instance : annotationList) { AnnotationTarget target = instance.target(); if (target instanceof FieldInfo) { FieldInfo fieldInfo = (FieldInfo) target; typeName = fieldInfo.type().toString(); if (typeName.startsWith("org.osgi.framework") || typeName.startsWith("org.osgi.service")) { declaringClass = fieldInfo.declaringClass(); return true; } } else if (target instanceof MethodInfo) { MethodInfo methodInfo = (MethodInfo) target; for (Type targetType : methodInfo.args()) { typeName = targetType.toString(); if (isInjectingOsgi(typeName)) { declaringClass = methodInfo.declaringClass(); return true; } } Type targetType = methodInfo.returnType(); typeName = targetType.toString(); if (isInjectingOsgi(typeName)) { declaringClass = methodInfo.declaringClass(); return true; } } else if (target instanceof MethodParameterInfo) { MethodParameterInfo methodParamInfo = (MethodParameterInfo) target; MethodInfo methodInfo = methodParamInfo.method(); Type targetType = methodInfo.args()[methodParamInfo.position()]; typeName = targetType.toString(); if (isInjectingOsgi(typeName)) { declaringClass = methodInfo.declaringClass(); return true; } } } } finally { if (result) { LOGGER.debugf("OSGi injection point of type '%s' detected: %s", typeName, declaringClass); } } return result; } }