View Javadoc
1   /*
2    *    Copyright 2013-2023 the original author or authors.
3    *
4    *    Licensed under the Apache License, Version 2.0 (the "License");
5    *    you may not use this file except in compliance with the License.
6    *    You may obtain a copy of the License at
7    *
8    *       https://www.apache.org/licenses/LICENSE-2.0
9    *
10   *    Unless required by applicable law or agreed to in writing, software
11   *    distributed under the License is distributed on an "AS IS" BASIS,
12   *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *    See the License for the specific language governing permissions and
14   *    limitations under the License.
15   */
16  package org.mybatis.cdi;
17  
18  import jakarta.enterprise.context.Dependent;
19  import jakarta.enterprise.context.spi.CreationalContext;
20  import jakarta.enterprise.inject.spi.Bean;
21  import jakarta.enterprise.inject.spi.InjectionPoint;
22  import jakarta.enterprise.inject.spi.PassivationCapable;
23  
24  import java.io.Serializable;
25  import java.lang.annotation.Annotation;
26  import java.lang.reflect.Proxy;
27  import java.lang.reflect.Type;
28  import java.util.Collections;
29  import java.util.HashSet;
30  import java.util.Set;
31  
32  import org.apache.ibatis.executor.ErrorContext;
33  import org.apache.ibatis.session.SqlSession;
34  import org.apache.ibatis.session.SqlSessionFactory;
35  import org.apache.ibatis.session.SqlSessionManager;
36  
37  /**
38   * Internal CDI metadata for a mapper bean.
39   *
40   * @author Frank D. Martinez [mnesarco]
41   */
42  public class MyBatisBean implements Bean<Object>, Serializable, PassivationCapable {
43  
44    private static final long serialVersionUID = 1L;
45  
46    protected final Class<Type> type;
47  
48    // Do not make this transient
49    protected final Set<Annotation> qualifiers;
50  
51    protected final String sqlSessionFactoryName;
52  
53    protected final String id;
54  
55    /**
56     * Instantiates a new my batis bean.
57     *
58     * @param id
59     *          the id
60     * @param type
61     *          the type
62     * @param qualifiers
63     *          the qualifiers
64     * @param sqlSessionFactoryName
65     *          the sql session factory name
66     */
67    public MyBatisBean(String id, Class<Type> type, Set<Annotation> qualifiers, String sqlSessionFactoryName) {
68      this.id = id;
69      this.type = type;
70      this.sqlSessionFactoryName = sqlSessionFactoryName;
71      if (qualifiers == null || qualifiers.isEmpty()) {
72        this.qualifiers = new HashSet<>();
73        this.qualifiers.add(new CDIUtils.SerializableDefaultAnnotationLiteral());
74        this.qualifiers.add(new CDIUtils.SerializableAnyAnnotationLiteral());
75      } else {
76        this.qualifiers = qualifiers;
77      }
78    }
79  
80    @Override
81    public Set<Type> getTypes() {
82      Set<Type> types = new HashSet<>();
83      types.add(this.type);
84      return types;
85    }
86  
87    @Override
88    public Set<Annotation> getQualifiers() {
89      return this.qualifiers;
90    }
91  
92    @Override
93    public Class<Dependent> getScope() {
94      return Dependent.class;
95    }
96  
97    @Override
98    public String getName() {
99      return null;
100   }
101 
102   @Override
103   public Set<Class<? extends Annotation>> getStereotypes() {
104     return Collections.emptySet();
105   }
106 
107   @Override
108   public Class<Type> getBeanClass() {
109     return this.type;
110   }
111 
112   @Override
113   public boolean isAlternative() {
114     return false;
115   }
116 
117   @Override
118   public Set<InjectionPoint> getInjectionPoints() {
119     return Collections.emptySet();
120   }
121 
122   @Override
123   public Object create(CreationalContext<Object> creationalContext) {
124     if (SqlSession.class.equals(this.type)) {
125       return findSqlSessionManager(creationalContext);
126     }
127     ErrorContext.instance().reset();
128     return Proxy.newProxyInstance(SqlSessionFactory.class.getClassLoader(), new Class[] { this.type },
129         new SerializableMapperProxy<>(this, creationalContext));
130   }
131 
132   @Override
133   public void destroy(Object instance, CreationalContext<Object> creationalContext) {
134     creationalContext.release();
135   }
136 
137   private <T> SqlSessionManager findSqlSessionManager(CreationalContext<T> creationalContext) {
138     SqlSessionFactory factory = CDIUtils.findSqlSessionFactory(this.sqlSessionFactoryName, this.qualifiers,
139         creationalContext);
140     return CDIUtils.getRegistry(creationalContext).getManager(factory);
141   }
142 
143   @Override
144   public String getId() {
145     return this.id;
146   }
147 
148 }