/** * Licensed to Apereo under one or more contributor license agreements. See the NOTICE file * distributed with this work for additional information regarding copyright ownership. Apereo * licenses this file to you 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 the * following location: * * <p>http://www.apache.org/licenses/LICENSE-2.0 * * <p>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. */ package org.apereo.portal.portlet.dao.jpa; import com.google.common.base.Function; import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.TypedQuery; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.JoinType; import javax.persistence.criteria.ParameterExpression; import javax.persistence.criteria.Root; import org.apache.commons.lang.Validate; import org.apereo.portal.jpa.BasePortalJpaDao; import org.apereo.portal.jpa.OpenEntityManager; import org.apereo.portal.portlet.dao.IPortletDefinitionDao; import org.apereo.portal.portlet.om.IPortletDefinition; import org.apereo.portal.portlet.om.IPortletDefinitionId; import org.apereo.portal.spring.tx.DialectAwareTransactional; import org.hibernate.dialect.PostgreSQL81Dialect; import org.springframework.dao.support.DataAccessUtils; import org.springframework.stereotype.Repository; /** * JPA implementation of the portlet definition DAO * */ @Repository public class JpaPortletDefinitionDao extends BasePortalJpaDao implements IPortletDefinitionDao { private CriteriaQuery<PortletDefinitionImpl> findAllPortletDefinitions; private CriteriaQuery<PortletDefinitionImpl> findDefinitionByNameQuery; private CriteriaQuery<PortletDefinitionImpl> findDefinitionByNameOrTitleQuery; private CriteriaQuery<PortletDefinitionImpl> searchDefinitionByNameOrTitleQuery; private ParameterExpression<String> nameParameter; private ParameterExpression<String> titleParameter; @Override public void afterPropertiesSet() throws Exception { this.nameParameter = this.createParameterExpression(String.class, "name"); this.titleParameter = this.createParameterExpression(String.class, "title"); this.findAllPortletDefinitions = this.createCriteriaQuery( new Function<CriteriaBuilder, CriteriaQuery<PortletDefinitionImpl>>() { @Override public CriteriaQuery<PortletDefinitionImpl> apply(CriteriaBuilder cb) { final CriteriaQuery<PortletDefinitionImpl> criteriaQuery = cb.createQuery(PortletDefinitionImpl.class); final Root<PortletDefinitionImpl> definitionRoot = criteriaQuery.from(PortletDefinitionImpl.class); criteriaQuery.select(definitionRoot); addFetches(definitionRoot); return criteriaQuery; } }); this.findDefinitionByNameQuery = this.createCriteriaQuery( new Function<CriteriaBuilder, CriteriaQuery<PortletDefinitionImpl>>() { @Override public CriteriaQuery<PortletDefinitionImpl> apply(CriteriaBuilder cb) { final CriteriaQuery<PortletDefinitionImpl> criteriaQuery = cb.createQuery(PortletDefinitionImpl.class); final Root<PortletDefinitionImpl> definitionRoot = criteriaQuery.from(PortletDefinitionImpl.class); criteriaQuery.select(definitionRoot); addFetches(definitionRoot); criteriaQuery.where( cb.equal( definitionRoot.get(PortletDefinitionImpl_.name), nameParameter)); return criteriaQuery; } }); this.findDefinitionByNameOrTitleQuery = this.createCriteriaQuery( new Function<CriteriaBuilder, CriteriaQuery<PortletDefinitionImpl>>() { @Override public CriteriaQuery<PortletDefinitionImpl> apply(CriteriaBuilder cb) { final CriteriaQuery<PortletDefinitionImpl> criteriaQuery = cb.createQuery(PortletDefinitionImpl.class); final Root<PortletDefinitionImpl> definitionRoot = criteriaQuery.from(PortletDefinitionImpl.class); criteriaQuery.select(definitionRoot); addFetches(definitionRoot); criteriaQuery.where( cb.or( cb.equal( definitionRoot.get( PortletDefinitionImpl_.name), nameParameter), cb.equal( definitionRoot.get( PortletDefinitionImpl_.title), titleParameter))); return criteriaQuery; } }); this.searchDefinitionByNameOrTitleQuery = this.createCriteriaQuery( new Function<CriteriaBuilder, CriteriaQuery<PortletDefinitionImpl>>() { @Override public CriteriaQuery<PortletDefinitionImpl> apply(CriteriaBuilder cb) { final CriteriaQuery<PortletDefinitionImpl> criteriaQuery = cb.createQuery(PortletDefinitionImpl.class); final Root<PortletDefinitionImpl> definitionRoot = criteriaQuery.from(PortletDefinitionImpl.class); criteriaQuery.select(definitionRoot); addFetches(definitionRoot); criteriaQuery.where( cb.or( cb.like( definitionRoot.get( PortletDefinitionImpl_.name), nameParameter), cb.like( definitionRoot.get( PortletDefinitionImpl_.title), titleParameter))); return criteriaQuery; } }); } /** Add all the fetches needed for completely loading the object graph */ protected void addFetches(final Root<PortletDefinitionImpl> definitionRoot) { definitionRoot .fetch(PortletDefinitionImpl_.portletPreferences, JoinType.LEFT) .fetch(PortletPreferencesImpl_.portletPreferences, JoinType.LEFT) .fetch(PortletPreferenceImpl_.values, JoinType.LEFT); definitionRoot.fetch(PortletDefinitionImpl_.parameters, JoinType.LEFT); definitionRoot.fetch(PortletDefinitionImpl_.localizations, JoinType.LEFT); } @Override @DialectAwareTransactional(value = PostgreSQL81Dialect.class, exclude = false) @PortalTransactionalReadOnly @OpenEntityManager(unitName = PERSISTENCE_UNIT_NAME) public IPortletDefinition getPortletDefinition(IPortletDefinitionId portletDefinitionId) { Validate.notNull(portletDefinitionId, "portletDefinitionId can not be null"); final long internalPortletDefinitionId = getNativePortletDefinitionId(portletDefinitionId); final PortletDefinitionImpl portletDefinition = this.getEntityManager() .find(PortletDefinitionImpl.class, internalPortletDefinitionId); return portletDefinition; } @Override @DialectAwareTransactional(value = PostgreSQL81Dialect.class, exclude = false) @PortalTransactionalReadOnly @OpenEntityManager(unitName = PERSISTENCE_UNIT_NAME) public IPortletDefinition getPortletDefinition(String portletDefinitionIdString) { Validate.notNull(portletDefinitionIdString, "portletDefinitionIdString can not be null"); PortletDefinitionImpl rslt = null; // default final Long internalPortletDefinitionId = getNativePortletDefinitionId(portletDefinitionIdString); if (internalPortletDefinitionId != null) { rslt = this.getEntityManager() .find(PortletDefinitionImpl.class, internalPortletDefinitionId); } return rslt; } @Override @DialectAwareTransactional(value = PostgreSQL81Dialect.class, exclude = false) @PortalTransactionalReadOnly @OpenEntityManager(unitName = PERSISTENCE_UNIT_NAME) public IPortletDefinition getPortletDefinitionByFname(String fname) { final NaturalIdQuery<PortletDefinitionImpl> query = this.createNaturalIdQuery(PortletDefinitionImpl.class); query.using(PortletDefinitionImpl_.fname, fname); return query.load(); } @Override @DialectAwareTransactional(value = PostgreSQL81Dialect.class, exclude = false) @PortalTransactionalReadOnly @OpenEntityManager(unitName = PERSISTENCE_UNIT_NAME) public IPortletDefinition getPortletDefinitionByName(String name) { final TypedQuery<PortletDefinitionImpl> query = this.createCachedQuery(this.findDefinitionByNameQuery); query.setParameter(this.nameParameter, name); final List<PortletDefinitionImpl> portletDefinitions = query.getResultList(); return DataAccessUtils.uniqueResult(portletDefinitions); } @Override @DialectAwareTransactional(value = PostgreSQL81Dialect.class, exclude = false) @PortalTransactionalReadOnly @OpenEntityManager(unitName = PERSISTENCE_UNIT_NAME) public List<IPortletDefinition> searchForPortlets(String term, boolean allowPartial) { final CriteriaQuery<PortletDefinitionImpl> criteriaQuery; if (allowPartial) { criteriaQuery = this.searchDefinitionByNameOrTitleQuery; term = "%" + term.toUpperCase() + "%"; } else { criteriaQuery = this.findDefinitionByNameOrTitleQuery; } final TypedQuery<PortletDefinitionImpl> query = this.createCachedQuery(criteriaQuery); query.setParameter("name", term); query.setParameter("title", term); final List<PortletDefinitionImpl> portletDefinitions = query.getResultList(); return new ArrayList<IPortletDefinition>(portletDefinitions); } @Override @PortalTransactional public void deletePortletDefinition(IPortletDefinition definition) { Validate.notNull(definition, "definition can not be null"); final IPortletDefinition persistentPortletDefinition; final EntityManager entityManager = this.getEntityManager(); if (entityManager.contains(definition)) { persistentPortletDefinition = definition; } else { persistentPortletDefinition = entityManager.merge(definition); } entityManager.remove(persistentPortletDefinition); } @Override @DialectAwareTransactional(value = PostgreSQL81Dialect.class, exclude = false) @PortalTransactionalReadOnly @OpenEntityManager(unitName = PERSISTENCE_UNIT_NAME) public List<IPortletDefinition> getPortletDefinitions() { final TypedQuery<PortletDefinitionImpl> query = this.createCachedQuery(this.findAllPortletDefinitions); final List<PortletDefinitionImpl> portletDefinitions = query.getResultList(); return new ArrayList<IPortletDefinition>( new LinkedHashSet<IPortletDefinition>(portletDefinitions)); } @Override @PortalTransactional public IPortletDefinition savePortletDefinition(IPortletDefinition portletDefinition) { Validate.notNull(portletDefinition, "portletDefinition can not be null"); Validate.notNull( portletDefinition.getType(), "portletDefinition portlet type can not be null"); Validate.notEmpty(portletDefinition.getFName(), "portletDefinition fname can not be null"); Validate.notEmpty(portletDefinition.getName(), "portletDefinition name can not be null"); Validate.notEmpty(portletDefinition.getTitle(), "portletDefinition title can not be null"); this.getEntityManager().persist(portletDefinition); return portletDefinition; } protected long getNativePortletDefinitionId(IPortletDefinitionId portletDefinitionId) { return Long.parseLong(portletDefinitionId.getStringId()); } protected Long getNativePortletDefinitionId(String portletDefinitionId) { Long rslt = null; // default try { rslt = Long.parseLong(portletDefinitionId); } catch (NumberFormatException nfe) { logger.warn( "The portletDefinitionId '{}' is not parsable to a valid portletId (long); null will be returned", portletDefinitionId); } return rslt; } }