com.thinkbiganalytics.metadata.jpa.feed.AugmentableQueryRepositoryFactory Maven / Gradle / Ivy
package com.thinkbiganalytics.metadata.jpa.feed;
/*-
* #%L
* kylo-operational-metadata-jpa
* %%
* Copyright (C) 2017 ThinkBig Analytics
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import com.thinkbiganalytics.security.AccessController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.jpa.repository.query.Procedure;
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactory;
import org.springframework.data.repository.core.RepositoryInformation;
import org.springframework.data.repository.core.RepositoryMetadata;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import javax.persistence.EntityManager;
/**
* Factory which knows how to create AugmentableRepositories with QueryAugmentors
*/
class AugmentableQueryRepositoryFactory extends JpaRepositoryFactory {
private static final Logger LOG = LoggerFactory.getLogger(AugmentableQueryRepositoryFactory.class);
private final EntityManager em;
private AccessController accessController;
AugmentableQueryRepositoryFactory(EntityManager em, AccessController accessController) {
super(em);
this.em = em;
this.accessController = accessController;
}
@Override
protected Object getTargetRepository(RepositoryInformation information) {
LOG.debug("AugmentableQueryRepositoryFactory.getTargetRepository");
Class> repositoryInterface = information.getRepositoryInterface();
if (isAugmentableRepository(repositoryInterface) && accessController.isEntityAccessControlled()) {
Class> domainType = information.getDomainType();
LOG.debug("Creating AugmentableQueryRepositoryImpl for repo interface {} and domain class {}", repositoryInterface, domainType);
RepositoryType annotation = AnnotationUtils.findAnnotation(repositoryInterface, RepositoryType.class);
Class extends AugmentableQueryRepositoryImpl> repoType = annotation.value();
try {
assertAugmentableRepositoryImplementsDeclaredMethods(repositoryInterface, repoType);
Constructor extends AugmentableQueryRepositoryImpl> constructor = repoType.getConstructor(JpaEntityInformation.class, EntityManager.class);
return constructor.newInstance(getEntityInformation(domainType), em);
} catch (Exception e) {
throw new IllegalStateException(String.format("Failed to create Augmentable Repository %s", repoType), e);
}
} else {
return super.getTargetRepository(information);
}
}
/**
* Augmentable Repository must implement methods declared by repository interface, otherwise non-implemented methods will be called on default
* repository implementation, such as SimpleJpaRepository, which are guaranteed not to be augmented e.g. not augmented for entity level access control.
* Here we cannot guarantee correct implementation, but implementation is the minimum contract.
*/
private void assertAugmentableRepositoryImplementsDeclaredMethods(Class> repositoryInterface, Class extends AugmentableQueryRepositoryImpl> repoType) {
Method[] methods = repositoryInterface.getDeclaredMethods();
for (Method method : methods) {
if (AnnotationUtils.findAnnotation(method, Query.class) != null) {
continue;
}
if (AnnotationUtils.findAnnotation(method, Procedure.class) != null) {
continue;
}
try {
repoType.getDeclaredMethod(method.getName(), method.getParameterTypes());
} catch (NoSuchMethodException e) {
throw new IllegalStateException(String.format("Augmentable Repository '%s' must implement method '%s' declared by repository interface '%s'", repoType, method.getName(), repositoryInterface));
}
}
}
@Override
protected Class> getRepositoryBaseClass(RepositoryMetadata metadata) {
LOG.debug("AugmentableQueryRepositoryFactory.getRepositoryBaseClass");
if (isAugmentableRepository(metadata.getRepositoryInterface()) && accessController.isEntityAccessControlled()) {
RepositoryType annotation = AnnotationUtils.findAnnotation(metadata.getRepositoryInterface(), RepositoryType.class);
return annotation.value();
} else {
return super.getRepositoryBaseClass(metadata);
}
}
private boolean isAugmentableRepository(Class> repositoryInterface) {
return AnnotationUtils.findAnnotation(repositoryInterface, RepositoryType.class) != null;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy