Java tutorial
/** * Copyright 2012-2013 Trento RISE * * 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. */ package eu.trentorise.smartcampus.ac.provider.repository.persistence; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.UUID; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.NoResultException; import javax.persistence.Persistence; import javax.persistence.PersistenceContext; import javax.persistence.PersistenceException; import javax.persistence.Query; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; import eu.trentorise.smartcampus.ac.provider.model.AcObject; import eu.trentorise.smartcampus.ac.provider.model.Attribute; import eu.trentorise.smartcampus.ac.provider.model.Authority; import eu.trentorise.smartcampus.ac.provider.model.User; import eu.trentorise.smartcampus.ac.provider.repository.AcDao; import eu.trentorise.smartcampus.ac.provider.repository.persistence.datamodel.AttributeEntity; import eu.trentorise.smartcampus.ac.provider.repository.persistence.datamodel.AuthorityEntity; import eu.trentorise.smartcampus.ac.provider.repository.persistence.datamodel.UserEntity; /** * Persistent implementation of AcDao interface * * @author mirko perillo * */ @Transactional @Repository("acPersistenceDao") public class AcDaoPersistenceImpl implements AcDao { EntityManagerFactory emf; @PersistenceContext EntityManager em; public AcDaoPersistenceImpl(String pu) { emf = Persistence.createEntityManagerFactory(pu); em = emf.createEntityManager(); } public AcDaoPersistenceImpl() { } /** * Persists a object with superclass AcObject. It returns the id of new * object * * @param acObj * object to create * @return the id of new object */ @Override public <T extends AcObject> long create(T acObj) { long id = 0; if (acObj != null) { if (acObj instanceof User) { if (readUser(((User) acObj).getAuthToken()) != null) { throw new IllegalArgumentException("This authToken is already present"); } if (((User) acObj).getSocialId() != 0 && readUserBySocialId(((User) acObj).getSocialId()) != null) { throw new IllegalArgumentException("This socialId is already present"); } // check authorities UserEntity toSave = PersistenceConverter.fromUser((User) acObj, true); try { checkAuthorities(toSave); } catch (IllegalArgumentException e) { throw e; } em.persist(toSave); id = toSave.getId(); } else if (acObj instanceof Authority) { if (readAuthorityByName(((Authority) acObj).getName()) != null) { throw new IllegalArgumentException("This name is already present"); } if (readAuthorityByUrl(((Authority) acObj).getRedirectUrl()) != null) { throw new IllegalArgumentException("This redirectUrl is already present"); } AuthorityEntity toSave = PersistenceConverter.fromAuthority((Authority) acObj, true); em.persist(toSave); id = toSave.getId(); } } return id; } @Override public String createSessionToken(long userId, Long expTime) { String tokenString = null; while (userExists(tokenString = generateAuthToken())) ; UserEntity ue = (UserEntity) em.find(UserEntity.class, userId); ue.setSessionAuthToken(tokenString); ue.setSessionExpTime(expTime); em.merge(ue); return tokenString; } @Override public String generateAuthToken() { return UUID.randomUUID().toString(); } /** * Updates the object, if objects is instance of User, new attributes are * persisted and added to user attributes. * * @param acObj * object to update * */ @Override public <T extends AcObject> void update(T acObj) { if (acObj != null) { if (acObj instanceof User) { UserEntity ue = em.find(UserEntity.class, acObj.getId()); if (ue == null) { throw new IllegalArgumentException("The object can't be updated because it doesn't exist"); } else { User u = (User) acObj; User userPresent = readUser(u.getAuthToken()); User userSocialIdPresent = readUserBySocialId(u.getSocialId()); if (userPresent != null && !userPresent.getId().equals(u.getId())) { throw new IllegalArgumentException( "The object can't be updated because authToken is already present"); } if (userSocialIdPresent != null && !userSocialIdPresent.getId().equals(u.getId())) { throw new IllegalArgumentException( "The object can't be updated because socialId is already present"); } ue.setAuthToken(u.getAuthToken()); ue.setExpTime(u.getExpTime()); ue.setSocialId(u.getSocialId()); try { ue = updateAttributes(ue, u); } catch (IllegalArgumentException e) { throw e; } em.merge(ue); } } else if (acObj instanceof Authority) { AuthorityEntity ae = em.find(AuthorityEntity.class, acObj.getId()); if (ae == null) { throw new IllegalArgumentException("The object can't be updated because it doesn't exist"); } else { Authority a = (Authority) acObj; Authority authNamePresent = readAuthorityByName(a.getName()); Authority authUrlPresent = readAuthorityByUrl(a.getRedirectUrl()); if (authNamePresent != null && !authNamePresent.getId().equals(a.getId())) { throw new IllegalArgumentException( "The object can't be updated because name is already present"); } if (authUrlPresent != null && !authUrlPresent.getId().equals(a.getId())) { throw new IllegalArgumentException( "The object can't be updated because redirectUrl is already present"); } ae.setName(a.getName()); ae.setRedirectUrl(a.getRedirectUrl()); em.merge(ae); } } } } private UserEntity updateAttributes(UserEntity ue, User u) throws IllegalArgumentException { List<AttributeEntity> toAdd = new ArrayList<AttributeEntity>(); for (Iterator<AttributeEntity> iterator = ue.getAttributeEntities().iterator(); iterator.hasNext();) { AttributeEntity ae = iterator.next(); iterator.remove(); em.remove(ae); } // for (AttributeEntity ae : ue.getAttributeEntities()) { // em.remove(ae); // } // for (Attribute a : u.getAttributes()) { // boolean found = false; // for (AttributeEntity ae : ue.getAttributeEntities()) { // if (found = PersistenceConverter.isSame(ae, a)) { // ae.setValue(a.getValue()); // break; // } // } // if (!found) { AttributeEntity newAe = new AttributeEntity(); newAe.setKey(a.getKey()); newAe.setValue(a.getValue()); AuthorityEntity auth = findAuthorityByName(a.getAuthority().getName()); if (auth == null) { throw new IllegalArgumentException( "The object can't be updated because one or more attributes referenced to an nonexistent authority"); } else { newAe.setAuthority(auth); toAdd.add(newAe); } // } } ue.getAttributeEntities().addAll(toAdd); return ue; } private AuthorityEntity findAuthorityByName(String name) { Query query = em.createQuery("from AuthorityEntity a where a.name= :name"); query.setParameter("name", name); try { return (AuthorityEntity) query.getSingleResult(); } catch (NoResultException e) { return null; } } private UserEntity findUserById(long id) { Query query = em.createQuery("from UserEntity a where a.id= :id"); query.setParameter("id", id); try { return (UserEntity) query.getSingleResult(); } catch (NoResultException e) { return null; } } private void checkAuthorities(UserEntity ue) throws IllegalArgumentException { try { for (AttributeEntity ae : ue.getAttributeEntities()) { AuthorityEntity authEntity = null; if ((authEntity = findAuthorityByName(ae.getAuthority().getName())) == null) { throw new IllegalArgumentException("Attribute referenced to a nonexistence authority"); } else { ae.setAuthority(authEntity); } } } catch (NullPointerException e) { } } /** * Deletes objects. If object is instance of User, it deletes all user * attributes * * @param acObj * object to delete * @return true if operation ended fine or false otherwise */ @Override public <T extends AcObject> boolean delete(T acObj) { if (acObj != null) { Class objectType = null; if (acObj instanceof User) { objectType = UserEntity.class; } else if (acObj instanceof Authority) { objectType = AuthorityEntity.class; } try { // remove all attribute of user // the cascade on new added attribute in update user doesn t // work fine if (acObj instanceof User) { UserEntity ue = findUserById(acObj.getId()); if (ue != null) { for (AttributeEntity attr : ue.getAttributeEntities()) { em.remove(attr); } } } em.remove(em.find(objectType, acObj.getId())); } catch (PersistenceException e) { throw new IllegalArgumentException("the object referenced to other objects, cannot be removed"); } return true; } return false; } /** * Returns the user given its id * * @param id * id of the user * @return the user or null if no user by that id exists */ @Override public User readUser(long id) { try { return PersistenceConverter.toUser((UserEntity) em.find(UserEntity.class, id)); } catch (NoResultException e) { return null; } } /** * Returns the user given its binded authentication token * * @param authToken * authentication token binded to the user * @return the user or null if no user is binded to the token */ @Override public User readUser(String authToken) { try { Query query = em.createQuery( "from UserEntity u where u.authToken= :authToken or u.sessionAuthToken = :authToken"); query.setParameter("authToken", authToken); try { UserEntity ue = (UserEntity) query.getSingleResult(); User u = PersistenceConverter.toUser(ue); if (authToken != null && authToken.equals(ue.getSessionAuthToken())) { u.setAuthToken(ue.getSessionAuthToken()); u.setExpTime(ue.getSessionExpTime()); } return u; } catch (NoResultException e) { return null; } } catch (NullPointerException e) { return null; } } private boolean userExists(String authToken) { try { Query query = em.createQuery( "from UserEntity u where u.authToken= :authToken or u.sessionAuthToken = :authToken"); query.setParameter("authToken", authToken); try { query.getSingleResult(); return true; } catch (NoResultException e) { return false; } } catch (Exception e) { return false; } } /** * Returns list of User matching given list of attributes or a empty list if * no user matches the attributes list * * @param attributes * list of attributes that user MUST have * @return the list of user that matches the list of attributes or a empty * list otherwise */ @Override public List<User> readUsers(List<Attribute> attributes) { Query query = em.createQuery("from UserEntity u"); List<User> result = PersistenceConverter.toUser(query.getResultList()); List<User> filtered = new ArrayList<User>(); for (User temp : result) { if (temp.getAttributes().containsAll(attributes)) { filtered.add(temp); } } return filtered; } /** * Returns all the authorities * * @return the collection of authorities present in the system */ @Override public Collection<Authority> readAuthorities() { Query query = em.createQuery("from AuthorityEntity a"); return PersistenceConverter.toAuthority(query.getResultList()); } /** * Returns authority by its name or null if no authority exists by the given * name * * @param name * name of authority to search * @return the authority or null if it doens't exist */ @Override public Authority readAuthorityByName(String name) { try { Query query = em.createQuery("from AuthorityEntity a where a.name = :name"); query.setParameter("name", name); try { return PersistenceConverter.toAuthority((AuthorityEntity) query.getSingleResult()); } catch (NoResultException e) { return null; } } catch (NullPointerException e) { return null; } } /** * Returns authority given its url * * @param url * the url of authority to search * @return authority of null if it doesn't exist */ @Override public Authority readAuthorityByUrl(String url) { try { Query query = em.createQuery("from AuthorityEntity a where a.redirectUrl = :url"); query.setParameter("url", url); try { return PersistenceConverter.toAuthority((AuthorityEntity) query.getSingleResult()); } catch (NoResultException e) { return null; } } catch (NullPointerException e) { return null; } } /** * Returns user given its social id * * @param socialId * the social id of user * @return user or null if it doesn't exist */ @Override public User readUserBySocialId(long socialId) { try { Query query = em.createQuery("from UserEntity u where u.socialId= :socialId"); query.setParameter("socialId", socialId); try { return PersistenceConverter.toUser((UserEntity) query.getSingleResult()); } catch (NoResultException e) { return null; } } catch (NullPointerException e) { return null; } } }