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.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.permission.PortalRuntimePermission;
022    import com.liferay.portal.security.lang.DoPrivilegedUtil;
023    import com.liferay.portal.util.ClassLoaderUtil;
024    
025    import java.security.PrivilegedAction;
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 DoPrivilegedUtil.wrap(
041                            new DynamicQueryPrivilegedAction(clazz, null));
042            }
043    
044            public DynamicQuery forClass(Class<?> clazz, ClassLoader classLoader) {
045                    clazz = getImplClass(clazz, classLoader);
046    
047                    return DoPrivilegedUtil.wrap(
048                            new DynamicQueryPrivilegedAction(clazz, null));
049            }
050    
051            public DynamicQuery forClass(Class<?> clazz, String alias) {
052                    clazz = getImplClass(clazz, null);
053    
054                    return DoPrivilegedUtil.wrap(
055                            new DynamicQueryPrivilegedAction(clazz, alias));
056            }
057    
058            public DynamicQuery forClass(
059                    Class<?> clazz, String alias, ClassLoader classLoader) {
060    
061                    clazz = getImplClass(clazz, classLoader);
062    
063                    return DoPrivilegedUtil.wrap(
064                            new DynamicQueryPrivilegedAction(clazz, alias));
065            }
066    
067            protected Class<?> getImplClass(Class<?> clazz, ClassLoader classLoader) {
068                    Class<?> implClass = clazz;
069    
070                    String className = clazz.getName();
071    
072                    if (!className.endsWith("Impl")) {
073                            if (classLoader == null) {
074                                    classLoader = ClassLoaderUtil.getContextClassLoader();
075                            }
076    
077                            Package pkg = clazz.getPackage();
078    
079                            String implClassName =
080                                    pkg.getName() + ".impl." + clazz.getSimpleName() + "Impl";
081    
082                            try {
083                                    implClass = getImplClass(implClassName, classLoader);
084                            }
085                            catch (Exception e1) {
086                                    if (classLoader != _portalClassLoader) {
087                                            try {
088                                                    implClass = getImplClass(
089                                                            implClassName, _portalClassLoader);
090                                            }
091                                            catch (Exception e2) {
092                                                    _log.error("Unable find model " + implClassName, e2);
093                                            }
094                                    }
095                                    else {
096                                            _log.error("Unable find model " + implClassName, e1);
097                                    }
098                            }
099                    }
100    
101                    PortalRuntimePermission.checkDynamicQuery(implClass);
102    
103                    return implClass;
104            }
105    
106            protected Class<?> getImplClass(
107                            String implClassName, ClassLoader classLoader)
108                    throws ClassNotFoundException {
109    
110                    Map<String, Class<?>> classes = _classes.get(classLoader);
111    
112                    if (classes == null) {
113                            classes = new HashMap<String, Class<?>>();
114    
115                            _classes.put(classLoader, classes);
116                    }
117    
118                    Class<?> clazz = classes.get(implClassName);
119    
120                    if (clazz == null) {
121                            clazz = classLoader.loadClass(implClassName);
122    
123                            classes.put(implClassName, clazz);
124                    }
125    
126                    return clazz;
127            }
128    
129            private static Log _log = LogFactoryUtil.getLog(
130                    DynamicQueryFactoryImpl.class);
131    
132            private Map<ClassLoader, Map<String, Class<?>>> _classes =
133                    new HashMap<ClassLoader, Map<String, Class<?>>>();
134            private ClassLoader _portalClassLoader =
135                    DynamicQueryFactoryImpl.class.getClassLoader();
136    
137            private class DynamicQueryPrivilegedAction
138                    implements PrivilegedAction<DynamicQuery> {
139    
140                    public DynamicQueryPrivilegedAction(Class<?> clazz, String alias) {
141                            _clazz = clazz;
142                            _alias = alias;
143                    }
144    
145                    public DynamicQuery run() {
146                            if (_alias != null) {
147                                    return new DynamicQueryImpl(
148                                            DetachedCriteria.forClass(_clazz, _alias));
149                            }
150    
151                            return new DynamicQueryImpl(DetachedCriteria.forClass(_clazz));
152                    }
153    
154                    private String _alias;
155                    private Class<?> _clazz;
156    
157            }
158    
159    }