001
014
015 package com.liferay.portal.dao.orm.hibernate;
016
017 import com.liferay.portal.kernel.concurrent.ConcurrentReferenceKeyHashMap;
018 import com.liferay.portal.kernel.dao.orm.DynamicQuery;
019 import com.liferay.portal.kernel.dao.orm.DynamicQueryFactory;
020 import com.liferay.portal.kernel.log.Log;
021 import com.liferay.portal.kernel.log.LogFactoryUtil;
022 import com.liferay.portal.kernel.memory.FinalizeManager;
023 import com.liferay.portal.kernel.security.pacl.permission.PortalRuntimePermission;
024 import com.liferay.portal.kernel.util.ClassLoaderUtil;
025 import com.liferay.portal.security.lang.DoPrivilegedUtil;
026
027 import java.security.PrivilegedAction;
028
029 import java.util.HashMap;
030 import java.util.Map;
031 import java.util.concurrent.ConcurrentMap;
032
033 import org.hibernate.criterion.DetachedCriteria;
034
035
038 public class DynamicQueryFactoryImpl implements DynamicQueryFactory {
039
040 @Override
041 public DynamicQuery forClass(Class<?> clazz) {
042 clazz = getImplClass(clazz, null);
043
044 return DoPrivilegedUtil.wrap(
045 new DynamicQueryPrivilegedAction(clazz, null));
046 }
047
048 @Override
049 public DynamicQuery forClass(Class<?> clazz, ClassLoader classLoader) {
050 clazz = getImplClass(clazz, classLoader);
051
052 return DoPrivilegedUtil.wrap(
053 new DynamicQueryPrivilegedAction(clazz, null));
054 }
055
056 @Override
057 public DynamicQuery forClass(Class<?> clazz, String alias) {
058 clazz = getImplClass(clazz, null);
059
060 return DoPrivilegedUtil.wrap(
061 new DynamicQueryPrivilegedAction(clazz, alias));
062 }
063
064 @Override
065 public DynamicQuery forClass(
066 Class<?> clazz, String alias, ClassLoader classLoader) {
067
068 clazz = getImplClass(clazz, classLoader);
069
070 return DoPrivilegedUtil.wrap(
071 new DynamicQueryPrivilegedAction(clazz, alias));
072 }
073
074 protected Class<?> getImplClass(Class<?> clazz, ClassLoader classLoader) {
075 Class<?> implClass = clazz;
076
077 String className = clazz.getName();
078
079 if (!className.endsWith("Impl")) {
080 if (classLoader == null) {
081 classLoader = ClassLoaderUtil.getContextClassLoader();
082 }
083
084 Package pkg = clazz.getPackage();
085
086 String implClassName =
087 pkg.getName() + ".impl." + clazz.getSimpleName() + "Impl";
088
089 try {
090 implClass = getImplClass(implClassName, classLoader);
091 }
092 catch (Exception e1) {
093 if (classLoader != _portalClassLoader) {
094 try {
095 implClass = getImplClass(
096 implClassName, _portalClassLoader);
097 }
098 catch (Exception e2) {
099 _log.error("Unable find model " + implClassName, e2);
100 }
101 }
102 else {
103 _log.error("Unable find model " + implClassName, e1);
104 }
105 }
106 }
107
108 PortalRuntimePermission.checkDynamicQuery(implClass);
109
110 return implClass;
111 }
112
113 protected Class<?> getImplClass(
114 String implClassName, ClassLoader classLoader)
115 throws ClassNotFoundException {
116
117 Map<String, Class<?>> classes = _classes.get(classLoader);
118
119 if (classes == null) {
120 classes = new HashMap<>();
121
122 _classes.put(classLoader, classes);
123 }
124
125 Class<?> clazz = classes.get(implClassName);
126
127 if (clazz == null) {
128 clazz = classLoader.loadClass(implClassName);
129
130 classes.put(implClassName, clazz);
131 }
132
133 return clazz;
134 }
135
136 private static final Log _log = LogFactoryUtil.getLog(
137 DynamicQueryFactoryImpl.class);
138
139 private static final
140 ConcurrentMap<ClassLoader, Map<String, Class<?>>> _classes =
141 new ConcurrentReferenceKeyHashMap<>(
142 FinalizeManager.WEAK_REFERENCE_FACTORY);
143
144 private final ClassLoader _portalClassLoader =
145 DynamicQueryFactoryImpl.class.getClassLoader();
146
147 private class DynamicQueryPrivilegedAction
148 implements PrivilegedAction<DynamicQuery> {
149
150 public DynamicQueryPrivilegedAction(Class<?> clazz, String alias) {
151 _clazz = clazz;
152 _alias = alias;
153 }
154
155 @Override
156 public DynamicQuery run() {
157 if (_alias != null) {
158 return new DynamicQueryImpl(
159 DetachedCriteria.forClass(_clazz, _alias));
160 }
161
162 return new DynamicQueryImpl(DetachedCriteria.forClass(_clazz));
163 }
164
165 private final String _alias;
166 private final Class<?> _clazz;
167
168 }
169
170 }