001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
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.DoPrivileged;
022    import com.liferay.portal.kernel.security.pacl.permission.PortalRuntimePermission;
023    import com.liferay.portal.kernel.util.ProxyUtil;
024    import com.liferay.portal.kernel.util.ReflectionUtil;
025    import com.liferay.portal.service.ResourceService;
026    import com.liferay.portal.service.persistence.ResourcePersistence;
027    
028    import java.util.Map;
029    import java.util.concurrent.ConcurrentHashMap;
030    
031    import org.springframework.context.ApplicationContext;
032    
033    /**
034     * @author Brian Wing Shun Chan
035     * @author Miguel Pastor
036     */
037    @DoPrivileged
038    @SuppressWarnings("deprecation")
039    public class BeanLocatorImpl implements BeanLocator {
040    
041            public static final String VELOCITY_SUFFIX = ".velocity";
042    
043            public BeanLocatorImpl(
044                    ClassLoader classLoader, ApplicationContext applicationContext) {
045    
046                    _classLoader = classLoader;
047                    _applicationContext = applicationContext;
048            }
049    
050            public ApplicationContext getApplicationContext() {
051                    return _applicationContext;
052            }
053    
054            public ClassLoader getClassLoader() {
055                    PortalRuntimePermission.checkGetClassLoader(_paclServletContextName);
056    
057                    return _classLoader;
058            }
059    
060            public String[] getNames() {
061                    return _applicationContext.getBeanDefinitionNames();
062            }
063    
064            public Class<?> getType(String name) {
065                    try {
066                            return _applicationContext.getType(name);
067                    }
068                    catch (Exception e) {
069                            throw new BeanLocatorException(e);
070                    }
071            }
072    
073            public <T> Map<String, T> locate(Class<T> clazz)
074                    throws BeanLocatorException {
075    
076                    try {
077                            return doLocate(clazz);
078                    }
079                    catch (SecurityException se) {
080                            throw se;
081                    }
082                    catch (Exception e) {
083                            throw new BeanLocatorException(e);
084                    }
085            }
086    
087            public Object locate(String name) throws BeanLocatorException {
088                    try {
089                            return doLocate(name);
090                    }
091                    catch (SecurityException se) {
092                            throw se;
093                    }
094                    catch (Exception e) {
095                            Object bean = _deprecatedBeans.get(name);
096    
097                            if (bean != null) {
098                                    return bean;
099                            }
100    
101                            if (name.equals(ResourcePersistence.class.getName())) {
102                                    bean = new ResourcePersistence() {};
103    
104                                    _deprecatedBeans.put(name, bean);
105    
106                                    return bean;
107                            }
108                            else if (name.equals(ResourceService.class.getName())) {
109                                    bean = new ResourceService() {};
110    
111                                    _deprecatedBeans.put(name, bean);
112    
113                                    return bean;
114                            }
115    
116                            throw new BeanLocatorException(e);
117                    }
118            }
119    
120            public void setPACLServletContextName(String paclServletContextName) {
121                    _paclServletContextName = paclServletContextName;
122            }
123    
124            /**
125             * This method ensures the calls stack is the proper length.
126             */
127            protected <T> Map<String, T> doLocate(Class<T> clazz) throws Exception {
128                    PortalRuntimePermission.checkGetBeanProperty(
129                            _paclServletContextName, clazz);
130    
131                    return _applicationContext.getBeansOfType(clazz);
132            }
133    
134            protected Object doLocate(String name) throws Exception {
135                    if (_log.isDebugEnabled()) {
136                            _log.debug("Locating " + name);
137                    }
138    
139                    if (name.equals("portletClassLoader")) {
140                            PortalRuntimePermission.checkGetClassLoader(
141                                    _paclServletContextName);
142                    }
143    
144                    Object bean = null;
145    
146                    if (name.endsWith(VELOCITY_SUFFIX)) {
147                            Object velocityBean = _velocityBeans.get(name);
148    
149                            if (velocityBean == null) {
150                                    String originalName = name.substring(
151                                            0, name.length() - VELOCITY_SUFFIX.length());
152    
153                                    Object curBean = _applicationContext.getBean(originalName);
154    
155                                    velocityBean = ProxyUtil.newProxyInstance(
156                                            _classLoader,
157                                            ReflectionUtil.getInterfaces(curBean, _classLoader),
158                                            new VelocityBeanHandler(curBean, _classLoader));
159    
160                                    _velocityBeans.put(name, velocityBean);
161                            }
162    
163                            bean = velocityBean;
164                    }
165                    else {
166                            bean = _applicationContext.getBean(name);
167                    }
168    
169                    if (bean == null) {
170                            return bean;
171                    }
172    
173                    return _pacl.getBean(bean, _classLoader);
174            }
175    
176            private static Log _log = LogFactoryUtil.getLog(BeanLocatorImpl.class);
177    
178            private static PACL _pacl = new NoPACL();
179    
180            private ApplicationContext _applicationContext;
181            private ClassLoader _classLoader;
182            private Map<String, Object> _deprecatedBeans =
183                    new ConcurrentHashMap<String, Object>();
184            private String _paclServletContextName;
185            private Map<String, Object> _velocityBeans =
186                    new ConcurrentHashMap<String, Object>();
187    
188            private static class NoPACL implements PACL {
189    
190                    public Object getBean(Object bean, ClassLoader classLoader) {
191                            return bean;
192                    }
193    
194            }
195    
196            public static interface PACL {
197    
198                    public Object getBean(Object bean, ClassLoader classLoader);
199    
200            }
201    
202    }