001    /**
002     *
003     *  Licensed to the Apache Software Foundation (ASF) under one or more
004     *  contributor license agreements.  See the NOTICE file distributed with
005     *  this work for additional information regarding copyright ownership.
006     *  The ASF licenses this file to You under the Apache License, Version 2.0
007     *  (the "License"); you may not use this file except in compliance with
008     *  the License.  You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     *  Unless required by applicable law or agreed to in writing, software
013     *  distributed under the License is distributed on an "AS IS" BASIS,
014     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     *  See the License for the specific language governing permissions and
016     *  limitations under the License.
017     */
018    
019    package org.apache.geronimo.naming.deployment;
020    
021    import java.util.Collections;
022    import java.util.HashMap;
023    import java.util.Map;
024    import java.util.Set;
025    
026    import javax.xml.namespace.QName;
027    
028    import org.apache.geronimo.common.DeploymentException;
029    import org.apache.geronimo.gbean.AbstractNameQuery;
030    import org.apache.geronimo.gbean.GBeanInfo;
031    import org.apache.geronimo.gbean.GBeanInfoBuilder;
032    import org.apache.geronimo.kernel.GBeanNotFoundException;
033    import org.apache.geronimo.kernel.config.Configuration;
034    import org.apache.geronimo.kernel.repository.Artifact;
035    import org.apache.geronimo.kernel.repository.Dependency;
036    import org.apache.geronimo.kernel.repository.Environment;
037    import org.apache.geronimo.kernel.repository.ImportType;
038    import org.apache.geronimo.naming.reference.PersistenceContextReference;
039    import org.apache.geronimo.xbeans.geronimo.naming.GerPatternType;
040    import org.apache.geronimo.xbeans.geronimo.naming.GerPersistenceContextRefDocument;
041    import org.apache.geronimo.xbeans.geronimo.naming.GerPersistenceContextRefType;
042    import org.apache.geronimo.xbeans.geronimo.naming.GerPersistenceContextTypeType;
043    import org.apache.geronimo.xbeans.geronimo.naming.GerPropertyType;
044    import org.apache.geronimo.schema.SchemaConversionUtils;
045    import org.apache.geronimo.schema.NamespaceElementConverter;
046    import org.apache.geronimo.deployment.service.EnvironmentBuilder;
047    import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
048    import org.apache.geronimo.j2ee.deployment.Module;
049    import org.apache.geronimo.j2ee.deployment.NamingBuilder;
050    import org.apache.xmlbeans.QNameSet;
051    import org.apache.xmlbeans.XmlObject;
052    
053    /**
054     * @version $Rev: 470597 $ $Date: 2006-11-02 15:30:55 -0800 (Thu, 02 Nov 2006) $
055     */
056    public class PersistenceContextRefBuilder implements NamingBuilder {
057        private static final QName PERSISTENCE_CONTEXT_REF_QNAME = GerPersistenceContextRefDocument.type.getDocumentElementName();
058        private static final QNameSet PERSISTENCE_CONTEXT_REF_QNAME_SET = QNameSet.singleton(PERSISTENCE_CONTEXT_REF_QNAME);
059    
060        private final Environment defaultEnvironment = new Environment();
061    
062        public PersistenceContextRefBuilder() {
063            defaultEnvironment.addDependency(new Dependency(new Artifact("org.apache.geronimo.modules", "geronimo-persistence-jpa10", (String)null, "jar"), ImportType.CLASSES));
064        }
065    
066        public void buildEnvironment(XmlObject specDD, XmlObject plan, Environment environment) {
067            if (getPersistenceContextRefs(plan).length > 0) {
068                EnvironmentBuilder.mergeEnvironments(environment, defaultEnvironment);
069            }
070        }
071    
072        public void initContext(XmlObject specDD, XmlObject plan, Configuration localConfiguration, Configuration remoteConfiguration, Module module) throws DeploymentException {
073        }
074    
075        public void buildNaming(XmlObject specDD, XmlObject plan, Configuration localConfiguration, Configuration remoteConfiguration, Module module, Map componentContext) throws DeploymentException {
076            XmlObject[] persistenceContextRefsUntyped = getPersistenceContextRefs(plan);
077            for (int i = 0; i < persistenceContextRefsUntyped.length; i++) {
078                XmlObject persistenceContextRefUntyped = persistenceContextRefsUntyped[i];
079                GerPersistenceContextRefType persistenceContextRef = (GerPersistenceContextRefType) persistenceContextRefUntyped.copy().changeType(GerPersistenceContextRefType.type);
080                if (persistenceContextRef == null) {
081                    throw new DeploymentException("Could not read persistenceContextRef " + persistenceContextRefUntyped + " as the correct xml type");
082                }
083                String persistenceContextRefName = persistenceContextRef.getPersistenceContextRefName();
084                boolean transactionScoped = !persistenceContextRef.getPersistenceContextType().equals(GerPersistenceContextTypeType.EXTENDED);
085                GerPropertyType[] propertyTypes = persistenceContextRef.getPropertyArray();
086                Map properties = new HashMap();
087                for (int j = 0; j < propertyTypes.length; j++) {
088                    GerPropertyType propertyType = propertyTypes[j];
089                    String key = propertyType.getKey();
090                    String value = propertyType.getValue();
091                    properties.put(key, value);
092                }
093    
094    
095                Set interfaceTypes = Collections.singleton("org.apache.geronimo.persistence.PersistenceUnitGBean");
096                AbstractNameQuery persistenceUnitNameQuery;
097                if (persistenceContextRef.isSetPersistenceUnitName()) {
098                    String persistenceUnitName = persistenceContextRef.getPersistenceUnitName();
099                    persistenceUnitNameQuery = new AbstractNameQuery(null, Collections.singletonMap("name", persistenceUnitName), interfaceTypes);
100                } else {
101                    GerPatternType gbeanLocator = persistenceContextRef.getPattern();
102    
103                    persistenceUnitNameQuery = ENCConfigBuilder.buildAbstractNameQuery(gbeanLocator, null, null, interfaceTypes);
104                }
105    
106                try {
107                    localConfiguration.findGBeanData(persistenceUnitNameQuery);
108                } catch (GBeanNotFoundException e) {
109                    throw new DeploymentException("Could not resolve reference at deploy time for query " + persistenceUnitNameQuery, e);
110                }
111    
112                PersistenceContextReference reference = new PersistenceContextReference(localConfiguration.getId(), persistenceUnitNameQuery, transactionScoped, properties);
113    
114                ((Map)componentContext.get(JNDI_KEY)).put(ENV + persistenceContextRefName, reference);
115    
116            }
117        }
118    
119        public QNameSet getSpecQNameSet() {
120            SchemaConversionUtils.registerNamespaceConversions(Collections.singletonMap(PERSISTENCE_CONTEXT_REF_QNAME.getLocalPart(), new NamespaceElementConverter(PERSISTENCE_CONTEXT_REF_QNAME.getNamespaceURI())));
121            return QNameSet.EMPTY;
122        }
123    
124        public QNameSet getPlanQNameSet() {
125            return PERSISTENCE_CONTEXT_REF_QNAME_SET;
126        }
127    
128        private XmlObject[] getPersistenceContextRefs(XmlObject plan) {
129            return plan == null? NO_REFS: plan.selectChildren(PersistenceContextRefBuilder.PERSISTENCE_CONTEXT_REF_QNAME_SET);
130        }
131    
132        public static final GBeanInfo GBEAN_INFO;
133    
134        static {
135            GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(PersistenceContextRefBuilder.class, NameFactory.MODULE_BUILDER);
136    
137            GBEAN_INFO = infoBuilder.getBeanInfo();
138        }
139    
140        public static GBeanInfo getGBeanInfo() {
141            return GBEAN_INFO;
142        }
143    }