001
014
015 package com.liferay.portal.dao.orm.hibernate;
016
017 import com.liferay.portal.kernel.annotation.ImplementationClassName;
018 import com.liferay.portal.kernel.concurrent.ConcurrentReferenceKeyHashMap;
019 import com.liferay.portal.kernel.dao.orm.DynamicQuery;
020 import com.liferay.portal.kernel.dao.orm.DynamicQueryFactory;
021 import com.liferay.portal.kernel.log.Log;
022 import com.liferay.portal.kernel.log.LogFactoryUtil;
023 import com.liferay.portal.kernel.memory.FinalizeManager;
024 import com.liferay.portal.kernel.security.pacl.permission.PortalRuntimePermission;
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 ImplementationClassName implementationClassName = clazz.getAnnotation(
076 ImplementationClassName.class);
077
078 if (implementationClassName == null) {
079 String className = clazz.getName();
080
081 if (!className.endsWith("Impl")) {
082 _log.error("Unable find model for " + clazz);
083 }
084
085 PortalRuntimePermission.checkDynamicQuery(clazz);
086
087 return clazz;
088 }
089
090 Class<?> implClass = clazz;
091
092 String implClassName = implementationClassName.value();
093
094 try {
095 implClass = getImplClass(implClassName, classLoader);
096 }
097 catch (Exception e1) {
098 if (classLoader != _portalClassLoader) {
099 try {
100 implClass = getImplClass(implClassName, _portalClassLoader);
101 }
102 catch (Exception e2) {
103 _log.error("Unable find model " + implClassName, e2);
104 }
105 }
106 else {
107 _log.error("Unable find model " + implClassName, e1);
108 }
109 }
110
111 PortalRuntimePermission.checkDynamicQuery(implClass);
112
113 return implClass;
114 }
115
116 protected Class<?> getImplClass(
117 String implClassName, ClassLoader classLoader)
118 throws ClassNotFoundException {
119
120 Map<String, Class<?>> classes = _classes.get(classLoader);
121
122 if (classes == null) {
123 classes = new HashMap<>();
124
125 _classes.put(classLoader, classes);
126 }
127
128 Class<?> clazz = classes.get(implClassName);
129
130 if (clazz == null) {
131 clazz = classLoader.loadClass(implClassName);
132
133 classes.put(implClassName, clazz);
134 }
135
136 return clazz;
137 }
138
139 private static final Log _log = LogFactoryUtil.getLog(
140 DynamicQueryFactoryImpl.class);
141
142 private static final
143 ConcurrentMap<ClassLoader, Map<String, Class<?>>> _classes =
144 new ConcurrentReferenceKeyHashMap<>(
145 FinalizeManager.WEAK_REFERENCE_FACTORY);
146
147 private final ClassLoader _portalClassLoader =
148 DynamicQueryFactoryImpl.class.getClassLoader();
149
150 private static class DynamicQueryPrivilegedAction
151 implements PrivilegedAction<DynamicQuery> {
152
153 public DynamicQueryPrivilegedAction(Class<?> clazz, String alias) {
154 _clazz = clazz;
155 _alias = alias;
156 }
157
158 @Override
159 public DynamicQuery run() {
160 if (_alias != null) {
161 return new DynamicQueryImpl(
162 DetachedCriteria.forClass(_clazz, _alias));
163 }
164
165 return new DynamicQueryImpl(DetachedCriteria.forClass(_clazz));
166 }
167
168 private final String _alias;
169 private final Class<?> _clazz;
170
171 }
172
173 }