001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portal.bean;
016    
017    import com.liferay.portal.kernel.bean.BeanLocator;
018    import com.liferay.portal.kernel.bean.BeanLocatorException;
019    import com.liferay.portal.kernel.log.Log;
020    import com.liferay.portal.kernel.log.LogFactoryUtil;
021    import com.liferay.portal.kernel.security.pacl.PACLConstants;
022    import com.liferay.portal.kernel.util.ProxyUtil;
023    import com.liferay.portal.kernel.util.StringPool;
024    import com.liferay.portal.security.pacl.PACLBeanHandler;
025    import com.liferay.portal.service.persistence.BasePersistence;
026    
027    import java.security.Permission;
028    
029    import java.util.ArrayList;
030    import java.util.List;
031    import java.util.Map;
032    import java.util.concurrent.ConcurrentHashMap;
033    
034    import org.springframework.context.ApplicationContext;
035    
036    /**
037     * @author Brian Wing Shun Chan
038     * @author Miguel Pastor
039     */
040    public class BeanLocatorImpl implements BeanLocator {
041    
042            public static final String VELOCITY_SUFFIX = ".velocity";
043    
044            public BeanLocatorImpl(
045                    ClassLoader classLoader, ApplicationContext applicationContext) {
046    
047                    _classLoader = classLoader;
048                    _applicationContext = applicationContext;
049            }
050    
051            public ApplicationContext getApplicationContext() {
052                    return _applicationContext;
053            }
054    
055            public ClassLoader getClassLoader() {
056                    return _classLoader;
057            }
058    
059            public String[] getNames() {
060                    return _applicationContext.getBeanDefinitionNames();
061            }
062    
063            public Class<?> getType(String name) {
064                    try {
065                            return _applicationContext.getType(name);
066                    }
067                    catch (Exception e) {
068                            throw new BeanLocatorException(e);
069                    }
070            }
071    
072            public <T> Map<String, T> locate(Class<T> clazz) {
073                    try {
074                            return _applicationContext.getBeansOfType(clazz);
075                    }
076                    catch (Exception e) {
077                            throw new BeanLocatorException(e);
078                    }
079            }
080    
081            public Object locate(String name) throws BeanLocatorException {
082                    try {
083                            return doLocate(name);
084                    }
085                    catch (SecurityException se) {
086                            throw se;
087                    }
088                    catch (Exception e) {
089                            throw new BeanLocatorException(e);
090                    }
091            }
092    
093            public void setPACLServletContextName(String paclServletContextName) {
094                    _paclServletContextName = paclServletContextName;
095            }
096    
097            public void setPACLWrapPersistence(boolean paclWrapPersistence) {
098                    _paclWrapPersistence = paclWrapPersistence;
099            }
100    
101            protected Object doLocate(String name) throws Exception {
102                    if (_log.isDebugEnabled()) {
103                            _log.debug("Locating " + name);
104                    }
105    
106                    if (name.equals("portletClassLoader")) {
107                            SecurityManager securityManager = System.getSecurityManager();
108    
109                            if (securityManager != null) {
110                                    Permission permission = new RuntimePermission(
111                                            PACLConstants.RUNTIME_PERMISSION_GET_CLASSLOADER.concat(
112                                                    StringPool.PERIOD).concat(_paclServletContextName));
113    
114                                    securityManager.checkPermission(permission);
115                            }
116                    }
117    
118                    if (name.endsWith(VELOCITY_SUFFIX)) {
119                            Object velocityBean = _velocityBeans.get(name);
120    
121                            if (velocityBean == null) {
122                                    String originalName = name.substring(
123                                            0, name.length() - VELOCITY_SUFFIX.length());
124    
125                                    Object bean = _applicationContext.getBean(originalName);
126    
127                                    velocityBean = ProxyUtil.newProxyInstance(
128                                            _classLoader, getInterfaces(bean),
129                                            new VelocityBeanHandler(bean, _classLoader));
130    
131                                    _velocityBeans.put(name, velocityBean);
132                            }
133    
134                            return velocityBean;
135                    }
136    
137                    Object bean = _applicationContext.getBean(name);
138    
139                    if (_paclWrapPersistence && (bean != null) &&
140                            (bean instanceof BasePersistence)) {
141    
142                            Object paclPersistenceBean = _paclPersistenceBeans.get(name);
143    
144                            if (paclPersistenceBean != null) {
145                                    return paclPersistenceBean;
146                            }
147    
148                            paclPersistenceBean = ProxyUtil.newProxyInstance(
149                                    _classLoader, getInterfaces(bean), new PACLBeanHandler(bean));
150    
151                            _paclPersistenceBeans.put(name, paclPersistenceBean);
152    
153                            return paclPersistenceBean;
154                    }
155    
156                    return bean;
157            }
158    
159            protected void getInterfaces(
160                    List<Class<?>> interfaceClasses, Class<?> clazz) {
161    
162                    for (Class<?> interfaceClass : clazz.getInterfaces()) {
163                            try {
164                                    interfaceClasses.add(
165                                            _classLoader.loadClass(interfaceClass.getName()));
166                            }
167                            catch (ClassNotFoundException cnfe) {
168                            }
169                    }
170            }
171    
172            protected Class<?>[] getInterfaces(Object object) {
173                    List<Class<?>> interfaceClasses = new ArrayList<Class<?>>();
174    
175                    Class<?> clazz = object.getClass();
176    
177                    getInterfaces(interfaceClasses, clazz);
178    
179                    Class<?> superClazz = clazz.getSuperclass();
180    
181                    while (superClazz != null) {
182                            getInterfaces(interfaceClasses, superClazz);
183    
184                            superClazz = superClazz.getSuperclass();
185                    }
186    
187                    return interfaceClasses.toArray(new Class<?>[interfaceClasses.size()]);
188            }
189    
190            private static Log _log = LogFactoryUtil.getLog(BeanLocatorImpl.class);
191    
192            private ApplicationContext _applicationContext;
193            private ClassLoader _classLoader;
194            private Map<String, Object> _paclPersistenceBeans =
195                    new ConcurrentHashMap<String, Object>();
196            private String _paclServletContextName;
197            private boolean _paclWrapPersistence;
198            private Map<String, Object> _velocityBeans =
199                    new ConcurrentHashMap<String, Object>();
200    
201    }