1 /*
2  * Copyright 2008-2019 by Emeric Vernat
3  *
4  *     This file is part of Java Melody.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18 package net.bull.javamelody;
19
20 import java.lang.reflect.InvocationHandler;
21 import java.lang.reflect.Method;
22
23 import org.springframework.beans.factory.config.BeanPostProcessor;
24 import org.springframework.core.PriorityOrdered;
25 import org.springframework.data.mongodb.MongoDatabaseFactory;
26 import org.springframework.data.mongodb.MongoDbFactory;
27
28 import com.mongodb.client.MongoDatabase;
29
30 import net.bull.javamelody.internal.common.LOG;
31
32 /**
33  * Post-processor Spring pour une éventuelle {@link MongoDbFactory} définie dans le fichier xml Spring.
34  * @author Emeric Vernat
35  */

36 @SuppressWarnings({ "deprecation""javadoc" })
37 public class SpringMongoDbFactoryBeanPostProcessor implements BeanPostProcessor, PriorityOrdered {
38     private static final boolean MONGO_DB_FACTORY_AVAILABLE = isMongoDbFactoryAvailable();
39     private static final boolean MONGO_DATABASE_FACTORY_AVAILABLE = isMongoDatabaseFactoryAvailable();
40
41     // l'interface PriorityOrdered place la priorité assez haute dans le contexte Spring
42     // quelle que soit la valeur de order
43     private int order = LOWEST_PRECEDENCE;
44
45     /** {@inheritDoc} */
46     @Override
47     public int getOrder() {
48         return order;
49     }
50
51     /**
52      * Définit la priorité dans le contexte Spring.
53      * @param order int
54      */

55     public void setOrder(int order) {
56         this.order = order;
57     }
58
59     /** {@inheritDoc} */
60     @Override
61     public Object postProcessBeforeInitialization(Object bean, String beanName) {
62         return bean;
63     }
64
65     /** {@inheritDoc} */
66     @Override
67     public Object postProcessAfterInitialization(Object bean, String beanName) {
68         if (MONGO_DB_FACTORY_AVAILABLE && bean instanceof MongoDbFactory) {
69             final MongoDbFactory mongoDbFactory = (MongoDbFactory) bean;
70             final InvocationHandler invocationHandler = new InvocationHandler() {
71                 /** {@inheritDoc} */
72                 @Override
73                 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
74                     Object result = method.invoke(mongoDbFactory, args);
75                     if (result instanceof MongoDatabase) {
76                         result = MongoWrapper.createDatabaseProxy((MongoDatabase) result);
77                     }
78                     return result;
79                 }
80             };
81             final MongoDbFactory factory = JdbcWrapper.createProxy(mongoDbFactory,
82                     invocationHandler);
83             LOG.debug("mongodb monitoring initialized");
84             return factory;
85         } else if (MONGO_DATABASE_FACTORY_AVAILABLE && bean instanceof MongoDatabaseFactory) {
86             final MongoDatabaseFactory mongoDatabaseFactory = (MongoDatabaseFactory) bean;
87             final InvocationHandler invocationHandler = new InvocationHandler() {
88                 /** {@inheritDoc} */
89                 @Override
90                 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
91                     Object result = method.invoke(mongoDatabaseFactory, args);
92                     if (result instanceof MongoDatabase) {
93                         result = MongoWrapper.createDatabaseProxy((MongoDatabase) result);
94                     }
95                     return result;
96                 }
97             };
98             final MongoDatabaseFactory factory = JdbcWrapper.createProxy(mongoDatabaseFactory,
99                     invocationHandler);
100             LOG.debug("mongodb monitoring initialized");
101             return factory;
102         }
103
104         return bean;
105     }
106
107     private static boolean isMongoDbFactoryAvailable() {
108         try {
109             Class.forName("org.springframework.data.mongodb.MongoDbFactory");
110             return true;
111         } catch (final ClassNotFoundException e) {
112             return false;
113         }
114     }
115
116     private static boolean isMongoDatabaseFactoryAvailable() {
117         try {
118             Class.forName("org.springframework.data.mongodb.MongoDatabaseFactory");
119             return true;
120         } catch (final ClassNotFoundException e) {
121             return false;
122         }
123     }
124 }
125