/* * JBoss, Home of Professional Open Source. * Copyright 2008, Red Hat Middleware LLC, 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.jpa.resolvers.strategy; import org.jboss.beans.metadata.api.annotations.Inject; import org.jboss.deployers.structure.spi.DeploymentUnit; import org.jboss.jpa.javaee.JavaEEModuleInformer; import org.jboss.jpa.resolvers.PersistenceUnitDependencyResolver; import org.jboss.metadata.jpa.spec.PersistenceMetaData; import org.jboss.metadata.jpa.spec.PersistenceUnitMetaData; /** * The spec compliant persistence unit search stragegy. * * To allow injection by class it has a base name. * * See EJB 3.0 6.2.2. * * @author <a href="mailto:cdewolf@redhat.com">Carlo de Wolf</a> * @version $Revision: $ */ public abstract class BaseSearchStrategy implements SearchStrategy { private JavaEEModuleInformer javaEEModuleInformer; public String findPersistenceUnitSupplier(PersistenceUnitDependencyResolver resolver, DeploymentUnit deploymentUnit, String persistenceUnitName) { String name = findWithinModule(resolver, deploymentUnit, persistenceUnitName, true); if(name == null) name = findWithinApplication(resolver, deploymentUnit.getTopLevel(), persistenceUnitName); return name; } protected String findWithinApplication(PersistenceUnitDependencyResolver resolver, DeploymentUnit unit, String persistenceUnitName) { String name = findWithinModule(resolver, unit, persistenceUnitName, false); if(name != null) return name; for(DeploymentUnit child : unit.getChildren()) { name = findWithinApplication(resolver, child, persistenceUnitName); if(name != null) return name; } return null; } /* * When finding the default persistence unit, the first persistence unit encountered is returned. * TODO: Maybe the name of unscoped persistence units should be changed, so only one can be deployed anyway. */ protected String findWithinModule(PersistenceUnitDependencyResolver resolver, DeploymentUnit unit, String persistenceUnitName, boolean allowScoped) { if(!allowScoped && isScoped(unit)) return null; PersistenceMetaData persistenceMetaData = unit.getAttachment(PersistenceMetaData.class); if(persistenceMetaData == null) return null; for(PersistenceUnitMetaData persistenceUnit : persistenceMetaData.getPersistenceUnits()) { if(persistenceUnitName == null || persistenceUnitName.length() == 0 || persistenceUnit.getName().equals(persistenceUnitName)) return resolver.createBeanName(unit, persistenceUnit.getName()); } return null; } protected static DeploymentUnit getDeploymentUnit(DeploymentUnit current, String path) { if(path.startsWith("/")) return getDeploymentUnit(current.getTopLevel(), path.substring(1)); if(path.startsWith("./")) return getDeploymentUnit(current, path.substring(2)); if(path.startsWith("../")) return getDeploymentUnit(current.getParent(), path.substring(3)); int i = path.indexOf('/'); String name; if(i == -1) name = path; else name = path.substring(0, i); for(DeploymentUnit child : current.getChildren()) { if(child.getSimpleName().equals(name)) return child; } throw new IllegalArgumentException("Can't find a deployment unit named " + name + " at " + current); } /* * EJB3 JPA 6.2.2: Persistence Unit Scope */ private boolean isScoped(DeploymentUnit unit) { JavaEEModuleInformer.ModuleType type = javaEEModuleInformer.getModuleType(unit); if(type == JavaEEModuleInformer.ModuleType.APP_CLIENT) return true; if(type == JavaEEModuleInformer.ModuleType.EJB) return true; if(type == JavaEEModuleInformer.ModuleType.WEB) return true; return false; } @Inject public void setJavaEEModuleInformer(JavaEEModuleInformer informer) { this.javaEEModuleInformer = informer; } }