001    /**
002     * Copyright (c) 2000-2012 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.dao.orm.hibernate;
016    
017    import com.liferay.portal.kernel.dao.orm.DynamicQuery;
018    import com.liferay.portal.kernel.dao.orm.DynamicQueryFactory;
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.security.pacl.permission.PortalServicePermission;
023    import com.liferay.portal.util.ClassLoaderUtil;
024    
025    import java.security.Permission;
026    
027    import java.util.HashMap;
028    import java.util.Map;
029    
030    import org.hibernate.criterion.DetachedCriteria;
031    
032    /**
033     * @author Brian Wing Shun Chan
034     */
035    public class DynamicQueryFactoryImpl implements DynamicQueryFactory {
036    
037            public DynamicQuery forClass(Class<?> clazz) {
038                    clazz = getImplClass(clazz, null);
039    
040                    return new DynamicQueryImpl(DetachedCriteria.forClass(clazz));
041            }
042    
043            public DynamicQuery forClass(Class<?> clazz, ClassLoader classLoader) {
044                    clazz = getImplClass(clazz, classLoader);
045    
046                    return new DynamicQueryImpl(DetachedCriteria.forClass(clazz));
047            }
048    
049            public DynamicQuery forClass(Class<?> clazz, String alias) {
050                    clazz = getImplClass(clazz, null);
051    
052                    return new DynamicQueryImpl(DetachedCriteria.forClass(clazz, alias));
053            }
054    
055            public DynamicQuery forClass(
056                    Class<?> clazz, String alias, ClassLoader classLoader) {
057    
058                    clazz = getImplClass(clazz, classLoader);
059    
060                    return new DynamicQueryImpl(DetachedCriteria.forClass(clazz, alias));
061            }
062    
063            protected Class<?> getImplClass(Class<?> clazz, ClassLoader classLoader) {
064                    Class<?> implClass = clazz;
065    
066                    String className = clazz.getName();
067    
068                    if (!className.endsWith("Impl")) {
069                            if (classLoader == null) {
070                                    classLoader = ClassLoaderUtil.getContextClassLoader();
071                            }
072    
073                            Package pkg = clazz.getPackage();
074    
075                            String implClassName =
076                                    pkg.getName() + ".impl." + clazz.getSimpleName() + "Impl";
077    
078                            try {
079                                    implClass = getImplClass(implClassName, classLoader);
080                            }
081                            catch (Exception e1) {
082                                    if (classLoader != _portalClassLoader) {
083                                            try {
084                                                    implClass = getImplClass(
085                                                            implClassName, _portalClassLoader);
086                                            }
087                                            catch (Exception e2) {
088                                                    _log.error("Unable find model " + implClassName, e2);
089                                            }
090                                    }
091                                    else {
092                                            _log.error("Unable find model " + implClassName, e1);
093                                    }
094                            }
095                    }
096    
097                    SecurityManager securityManager = System.getSecurityManager();
098    
099                    if (securityManager != null) {
100                            Permission permission = new PortalServicePermission(
101                                    PACLConstants.PORTAL_SERVICE_PERMISSION_DYNAMIC_QUERY,
102                                    implClass, null);
103    
104                            securityManager.checkPermission(permission);
105                    }
106    
107                    return implClass;
108            }
109    
110            protected Class<?> getImplClass(
111                            String implClassName, ClassLoader classLoader)
112                    throws ClassNotFoundException {
113    
114                    Map<String, Class<?>> classes = _classes.get(classLoader);
115    
116                    if (classes == null) {
117                            classes = new HashMap<String, Class<?>>();
118    
119                            _classes.put(classLoader, classes);
120                    }
121    
122                    Class<?> clazz = classes.get(implClassName);
123    
124                    if (clazz == null) {
125                            clazz = classLoader.loadClass(implClassName);
126    
127                            classes.put(implClassName, clazz);
128                    }
129    
130                    return clazz;
131            }
132    
133            private static Log _log = LogFactoryUtil.getLog(
134                    DynamicQueryFactoryImpl.class);
135    
136            private Map<ClassLoader, Map<String, Class<?>>> _classes =
137                    new HashMap<ClassLoader, Map<String, Class<?>>>();
138            private ClassLoader _portalClassLoader =
139                    DynamicQueryFactoryImpl.class.getClassLoader();
140    
141    }