Java tutorial
package com.hiperf.common.ui.server.storage.impl; import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.io.IOException; import java.io.Serializable; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.text.MessageFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import java.util.ResourceBundle; import java.util.Set; import java.util.StringTokenizer; import java.util.logging.Level; import java.util.logging.Logger; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.persistence.Basic; import javax.persistence.CollectionTable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.FetchType; import javax.persistence.FlushModeType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.IdClass; import javax.persistence.JoinColumn; import javax.persistence.ManyToMany; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; import javax.persistence.OneToOne; import javax.persistence.Persistence; import javax.persistence.Query; import javax.persistence.Table; import javax.persistence.metamodel.EntityType; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.transaction.UserTransaction; import javax.validation.ConstraintViolation; import javax.validation.Validation; import javax.validation.Validator; import javax.validation.ValidatorFactory; import org.apache.commons.fileupload.FileItem; import org.apache.commons.lang3.StringUtils; import org.gwtgen.api.shared.INakedObject; import org.hibernate.exception.SQLGrammarException; import com.hiperf.common.ui.client.IAuditable; import com.hiperf.common.ui.client.ILazy; import com.hiperf.common.ui.client.ObjectsToPersist; import com.hiperf.common.ui.client.exception.PersistenceException; import com.hiperf.common.ui.server.UTF8Control; import com.hiperf.common.ui.server.listener.LicenseProvider; import com.hiperf.common.ui.server.storage.AbstractPersistenceHelper; import com.hiperf.common.ui.server.storage.IPersistenceHelper; import com.hiperf.common.ui.server.tx.ITransaction; import com.hiperf.common.ui.server.tx.JtaTransaction; import com.hiperf.common.ui.server.tx.LocalTransaction; import com.hiperf.common.ui.server.tx.TransactionContext; import com.hiperf.common.ui.server.tx.TransactionException; import com.hiperf.common.ui.server.util.ExcelHelper; import com.hiperf.common.ui.server.util.IOUtils; import com.hiperf.common.ui.server.util.IdHolder; import com.hiperf.common.ui.server.util.LinkFileInfo; import com.hiperf.common.ui.shared.HeaderInfo; import com.hiperf.common.ui.shared.IConstants; import com.hiperf.common.ui.shared.ILazyId; import com.hiperf.common.ui.shared.LazyList; import com.hiperf.common.ui.shared.LazySet; import com.hiperf.common.ui.shared.NakedObjectHandler; import com.hiperf.common.ui.shared.PersistenceManager; import com.hiperf.common.ui.shared.model.Filter; import com.hiperf.common.ui.shared.model.FilterValue; import com.hiperf.common.ui.shared.model.Label; import com.hiperf.common.ui.shared.model.LanguageEnum; import com.hiperf.common.ui.shared.model.ScreenConfig; import com.hiperf.common.ui.shared.model.ScreenHeaderInfo; import com.hiperf.common.ui.shared.model.ScreenLabels; import com.hiperf.common.ui.shared.util.CollectionInfo; import com.hiperf.common.ui.shared.util.NakedObjectsList; import com.hiperf.common.ui.shared.util.TableConfig; public final class PersistenceHelper extends AbstractPersistenceHelper { private static final Logger logger = Logger.getLogger(PersistenceHelper.class.getName()); private static final Object[] nullArg = new Object[1]; static { nullArg[0] = null; } private TYPE type; private ITransaction tx = null; private EntityManagerFactory emf; private ThreadLocal<EntityManager> emByThread; private static final Map<String, String> tableByClassName = new HashMap<String, String>(); private static final Map<String, PropertyDescriptor[]> propertyDescriptorsByClassName = new HashMap<String, PropertyDescriptor[]>(); private static final Map<String, Set<PropertyDescriptor>> idsByClassName = new HashMap<String, Set<PropertyDescriptor>>(); private static final Set<String> generatedIdClasses = new HashSet<String>(); private static final Map<String, Set<PropertyDescriptor>> collectionsByClassName = new Hashtable<String, Set<PropertyDescriptor>>(); private static final Map<String, Set<PropertyDescriptor>> lazysByClassName = new Hashtable<String, Set<PropertyDescriptor>>(); private static final Map<String, Set<PropertyDescriptor>> eagerObjectsByClassName = new Hashtable<String, Set<PropertyDescriptor>>(); private static final Map<String, Set<LinkFileInfo>> linkedFilesByClassName = new HashMap<String, Set<LinkFileInfo>>(); private static final ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory(); private PersistenceHelper(TYPE t, String unitName) { startLicenseCheck(); this.type = t; try { emf = Persistence.createEntityManagerFactory(unitName); emByThread = new ThreadLocal<EntityManager>(); } catch (Exception ee) { logger.log(Level.SEVERE, "Exception while init Persistence.xml...", ee); throw new RuntimeException(ee); } if (this.type.equals(TYPE.JTA)) { try { Context c = new InitialContext(); tx = new JtaTransaction((UserTransaction) c.lookup("java:comp/UserTransaction")); } catch (NamingException e) { logger.log(Level.SEVERE, "Exception while initializing PersistenceHelper in JTA...", e); type = TYPE.LOCAL; } } if (emf.getMetamodel().getEntities() != null && !emf.getMetamodel().getEntities().isEmpty()) { for (EntityType e : emf.getMetamodel().getEntities()) { try { initClassMapping(e.getBindableJavaType().getName()); } catch (Exception e1) { logger.log(Level.SEVERE, "Exception", e1); } } } endLicenseCheck(); } private void endLicenseCheck() { LicenseProvider lp = LicenseProvider.getInstance(); if (lp != null) lp.endLicenseCheck(); } private void startLicenseCheck() { LicenseProvider lp = LicenseProvider.getInstance(); if (lp != null) lp.startLicenseCheck(); } public static IPersistenceHelper createInstance(TYPE t, String unitName) { if (instance == null) { instance = new PersistenceHelper(t, unitName); } return instance; } @Override public TransactionContext createTransactionalContext() { EntityManager em = getEntityManager(); switch (this.type) { case LOCAL: return new TransactionContext(new LocalTransaction(em.getTransaction()), em); default: return new TransactionContext(tx, em); } } @Override public EntityManager getEntityManager() { EntityManager em = emByThread.get(); if (em == null || !em.isOpen()) { em = emf.createEntityManager(); em.setFlushMode(FlushModeType.COMMIT); emByThread.set(em); } return em; } @Override public List<INakedObject> deproxyEntities(String className, List<INakedObject> list, boolean root, Map<String, Map<Object, Object>> oldIdByNewId) throws PersistenceException { try { Set<PropertyDescriptor> idPds = idsByClassName.get(className); EntityManager em = getEntityManager(); Map<String, Map<com.hiperf.common.ui.shared.util.Id, INakedObject>> deproxyContext = new HashMap<String, Map<com.hiperf.common.ui.shared.util.Id, INakedObject>>(); List<INakedObject> l2 = new ArrayList<INakedObject>(list.size()); for (INakedObject no : list) { l2.add(deproxyNakedObject(root, collectionsByClassName.get(className), lazysByClassName.get(className), eagerObjectsByClassName.get(className), linkedFilesByClassName.get(className), no, idPds, oldIdByNewId, em, deproxyContext)); } return l2; } catch (Exception e) { logger.log(Level.SEVERE, "Exception in deproxyEntities", e); throw new PersistenceException("Exception in deproxyEntities...", e); } } @Override public INakedObject deproxyNakedObject(INakedObject no, EntityManager em, Map<String, Map<com.hiperf.common.ui.shared.util.Id, INakedObject>> deproxyContext) throws PersistenceException { if (no != null) { try { String className = getClassName(no); Set<PropertyDescriptor> idsPd = idsByClassName.get(className); return deproxyNakedObject(true, collectionsByClassName.get(className), lazysByClassName.get(className), eagerObjectsByClassName.get(className), linkedFilesByClassName.get(className), no, idsPd, null, em, deproxyContext); } catch (Exception e) { logger.log(Level.SEVERE, "Exception in deproxyNakedObject", e); throw new PersistenceException("Exception in deproxyNakedObject...", e); } } return null; } private INakedObject deproxyNakedObject(boolean root, Set<PropertyDescriptor> collections, Set<PropertyDescriptor> lazys, Set<PropertyDescriptor> eagers, Set<LinkFileInfo> linkedFiles, INakedObject no, Set<PropertyDescriptor> idPds, Map<String, Map<Object, Object>> oldIdByNewId, EntityManager em, Map<String, Map<com.hiperf.common.ui.shared.util.Id, INakedObject>> deproxyContext) throws IllegalAccessException, InvocationTargetException, InstantiationException, IntrospectionException, ClassNotFoundException, PersistenceException { String name = getClassName(no); if (isProxy(no, name)) no = clone(no, name); Map<com.hiperf.common.ui.shared.util.Id, INakedObject> map = deproxyContext.get(name); if (map == null) { map = new HashMap<com.hiperf.common.ui.shared.util.Id, INakedObject>(); deproxyContext.put(name, map); } com.hiperf.common.ui.shared.util.Id noId = getId(no, idsByClassName.get(name)); if (map.containsKey(noId)) return no; map.put(noId, no); if (root && linkedFiles != null && !linkedFiles.isEmpty()) { for (LinkFileInfo a : linkedFiles) { Object fileId = a.getLocalFileIdGetter().invoke(no, new Object[0]); if (fileId != null) a.getLocalFileNameSetter().invoke(no, getFileName(a.getFileClassName(), a.getFileNameField(), fileId, getEntityManager())); } } if (collections != null) { for (PropertyDescriptor pd : collections) { Method readMethod = pd.getReadMethod(); Method writeMethod = pd.getWriteMethod(); Object o = readMethod.invoke(no, new Object[0]); if (o != null) { if (root) { Collection orig = (Collection) o; boolean processed = false; Type type = readMethod.getGenericReturnType(); Class classInCollection = null; if (type instanceof ParameterizedType) { classInCollection = (Class) ((ParameterizedType) type).getActualTypeArguments()[0]; } if (classInCollection != null) { if (Number.class.isAssignableFrom(classInCollection) || String.class.equals(classInCollection) || Boolean.class.equals(classInCollection)) { Collection targetColl; int size = orig.size(); if (List.class.isAssignableFrom(readMethod.getReturnType())) { targetColl = new ArrayList(size); } else { targetColl = new HashSet(size); } if (size > 0) targetColl.addAll(orig); writeMethod.invoke(no, targetColl); processed = true; } } if (!processed) { //deproxyCollection(no, readMethod, writeMethod, orig, oldIdByNewId, em, deproxyContext); com.hiperf.common.ui.shared.util.Id id = getId(no, idPds); CollectionInfo ci = null; if (!id.isLocal()) { String className = getClassName(no); String attName = pd.getName(); ci = getCollectionInfo(em, id, className, attName); } if (List.class.isAssignableFrom(readMethod.getReturnType())) { if (ci != null) writeMethod.invoke(no, new LazyList<INakedObject>(ci.getSize(), ci.getDescription())); else writeMethod.invoke(no, new LazyList<INakedObject>()); } else { if (ci != null) writeMethod.invoke(no, new LazySet<INakedObject>(ci.getSize(), ci.getDescription())); else writeMethod.invoke(no, new LazySet<INakedObject>()); } } } else { if (List.class.isAssignableFrom(readMethod.getReturnType())) { writeMethod.invoke(no, new LazyList<INakedObject>()); } else { writeMethod.invoke(no, new LazySet<INakedObject>()); } } } } } if (lazys != null) { for (PropertyDescriptor pd : lazys) { Method readMethod = pd.getReadMethod(); Object o = readMethod.invoke(no, new Object[0]); if (o != null) { Class<?> targetClass = pd.getPropertyType(); if (root) { String targetClassName = targetClass.getName(); if (isProxy(o, targetClassName)) { o = deproxyObject(targetClass, o); } Set<PropertyDescriptor> ids = idsByClassName.get(targetClassName); o = deproxyNakedObject(root, collectionsByClassName.get(targetClassName), lazysByClassName.get(targetClassName), eagerObjectsByClassName.get(targetClassName), linkedFilesByClassName.get(targetClassName), (INakedObject) o, ids, oldIdByNewId, em, deproxyContext); pd.getWriteMethod().invoke(no, o); } else { Object lazyObj = newLazyObject(targetClass); pd.getWriteMethod().invoke(no, lazyObj); } } } } if (eagers != null) { for (PropertyDescriptor pd : eagers) { String targetClassName = pd.getPropertyType().getName(); Method readMethod = pd.getReadMethod(); Object o = readMethod.invoke(no, new Object[0]); if (o != null) { Set<PropertyDescriptor> ids = idsByClassName.get(targetClassName); deproxyNakedObject(root, collectionsByClassName.get(targetClassName), lazysByClassName.get(targetClassName), eagerObjectsByClassName.get(targetClassName), linkedFilesByClassName.get(targetClassName), (INakedObject) o, ids, oldIdByNewId, em, deproxyContext); } } } if (oldIdByNewId != null && idPds != null) { Map<Object, Object> map2 = oldIdByNewId.get(no.getClass().getName()); if (map2 != null && !map2.isEmpty()) { for (PropertyDescriptor pd : idPds) { Object id = pd.getReadMethod().invoke(no, StorageService.emptyArg); Object oldId = map2.get(id); if (oldId != null) { pd.getWriteMethod().invoke(no, new Object[] { oldId }); } } } } try { em.remove(no); } catch (Exception e) { } return no; } private INakedObject clone(INakedObject no, String name) { try { Class<?> cc = Class.forName(name); return (INakedObject) newLazyObject(cc); // PropertyDescriptor[] pds = propertyDescriptorsByClassName.get(name); // for(PropertyDescriptor pd : pds) { // if(pd.getReadMethod() != null && pd.getWriteMethod() != null) { // pd.getWriteMethod().invoke(o, pd.getReadMethod().invoke(no, new String[0])); // } // } // return o; } catch (InstantiationException | IllegalAccessException | ClassNotFoundException | IllegalArgumentException | InvocationTargetException | IntrospectionException | PersistenceException e) { logger.log(Level.SEVERE, "Exception while cloning...", e); } return no; } private String getClassName(INakedObject no) { String className = no.getClass().getName(); int idx = className.indexOf("_$$_"); if (idx > 0) className = className.substring(0, idx); return className; } @Override public CollectionInfo getCollectionInfo(EntityManager em, com.hiperf.common.ui.shared.util.Id id, String className, String attName) { CollectionInfo ci; String currentFilter; String jpql; int count = 0; String desc = null; jpql = "select size(o." + attName + ") from " + className + " o"; currentFilter = getIdClause(id); jpql += " where " + currentFilter; Query q = em.createQuery(jpql); count = getSize(id, q); if (count == 1) { jpql = "select o." + attName + " from " + className + " o where " + currentFilter; q = em.createQuery(jpql); int i = 0; for (Object idObj : id.getFieldValues()) { q.setParameter("id" + i, idObj); } desc = q.getResultList().get(0).toString(); } ci = new CollectionInfo(count, desc); return ci; } @Override public String getFileName(String fileClassName, String fileNameField, Object fileId) throws PersistenceException { EntityManager em = null; try { em = getEntityManager(); return getFileName(fileClassName, fileNameField, fileId, em); } catch (Exception e) { logger.log(Level.SEVERE, "Exception in getFileName", e); throw new PersistenceException("Exception in getFileName", e); } finally { closeEntityManager(em); } } private String getFileName(String fileClassName, String fileNameField, Object fileId, EntityManager em) throws PersistenceException { String idFieldName = getIdFieldFromFileStorageClass(fileClassName); List<String> l = em.createQuery( "select o." + fileNameField + " from " + fileClassName + " o where o." + idFieldName + " = :id") .setParameter("id", fileId).getResultList(); if (l != null && !l.isEmpty()) { return l.get(0); } return null; } private static boolean isProxy(Object o, String realClassName) { return !o.getClass().getName().equals(realClassName); } private static Object deproxyObject(Class<?> targetClass, Object proxy) throws InstantiationException, IllegalAccessException, IntrospectionException, InvocationTargetException, PersistenceException, ClassNotFoundException { Object target = targetClass.newInstance(); PropertyDescriptor[] targetPds = Introspector.getBeanInfo(targetClass).getPropertyDescriptors(); for (PropertyDescriptor targetPd : targetPds) { if (targetPd.getReadMethod() != null && targetPd.getWriteMethod() != null) { Object o = targetPd.getReadMethod().invoke(proxy, new Object[0]); if (o != null) { Class<?> propertyType = targetPd.getPropertyType(); String className = propertyType.getName(); if (!propertyType.isPrimitive() && !o.getClass().isPrimitive() && !(o instanceof Date) && isProxy(o, className)) { if (Set.class.isAssignableFrom(propertyType)) { o = new LazySet(); } else if (List.class.isAssignableFrom(propertyType)) { o = new LazyList(); } else o = newLazyObject(propertyType); } targetPd.getWriteMethod().invoke(target, o); } } } return target; } private void deproxyCollection(INakedObject no, Method readMethod, Method writeMethod, Collection originalColl, Map<String, Map<Object, Object>> oldIdByNewId, EntityManager em, Map<String, Map<com.hiperf.common.ui.shared.util.Id, INakedObject>> deproxyContext) throws InstantiationException, IllegalAccessException, IntrospectionException, InvocationTargetException, ClassNotFoundException, PersistenceException { if (!(originalColl instanceof ILazy)) { Collection targetColl; if (List.class.isAssignableFrom(readMethod.getReturnType())) { targetColl = new ArrayList(originalColl.size()); } else { targetColl = new HashSet(originalColl.size()); } Type type = readMethod.getGenericReturnType(); Class classInCollection = null; if (type instanceof ParameterizedType) { classInCollection = (Class) ((ParameterizedType) type).getActualTypeArguments()[0]; } if (classInCollection != null) { if (Number.class.isAssignableFrom(classInCollection) || String.class.equals(classInCollection) || Boolean.class.equals(classInCollection)) { targetColl.addAll((Collection) readMethod.invoke(no, new Object[0])); } else { for (Object obj : originalColl) { String targetClassName = classInCollection.getName(); if (isProxy(obj, targetClassName)) { obj = deproxyObject(classInCollection, obj); } Set<PropertyDescriptor> idPds = idsByClassName.get(targetClassName); targetColl.add(deproxyNakedObject(false, collectionsByClassName.get(targetClassName), lazysByClassName.get(targetClassName), eagerObjectsByClassName.get(targetClassName), linkedFilesByClassName.get(targetClassName), (INakedObject) obj, idPds, oldIdByNewId, em, deproxyContext)); } } writeMethod.invoke(no, targetColl); } } } private static final Object newLazyObject(Class<?> targetClass) throws InstantiationException, IllegalAccessException, ClassNotFoundException, IntrospectionException, IllegalArgumentException, InvocationTargetException, PersistenceException { Object lazyObj = targetClass.newInstance(); String name = targetClass.getName(); Set<PropertyDescriptor> pds = idsByClassName.get(name); for (PropertyDescriptor pd : pds) { pd.getWriteMethod().invoke(lazyObj, getLazyValue(pd.getPropertyType())); } return lazyObj; } private static final Object getLazyValue(Class<?> c) { if (c.equals(Integer.class) || c.equals(int.class)) { return ILazyId.INT; } if (c.equals(Long.class) || c.equals(long.class)) { return ILazyId.LONG; } if (c.equals(String.class)) { return ILazyId.STRING; } //TODO : Object class Type .... return null; } private static final Set<PropertyDescriptor> initClassMapping(String className) throws ClassNotFoundException, IntrospectionException, PersistenceException { Set<PropertyDescriptor> ids = new HashSet<PropertyDescriptor>(); Set<PropertyDescriptor> collections = new HashSet<PropertyDescriptor>(); Set<PropertyDescriptor> lazys = new HashSet<PropertyDescriptor>(); Set<PropertyDescriptor> eagers = new HashSet<PropertyDescriptor>(); Set<LinkFileInfo> linkedFiles = new HashSet<LinkFileInfo>(); idsByClassName.put(className, ids); collectionsByClassName.put(className, collections); lazysByClassName.put(className, lazys); eagerObjectsByClassName.put(className, eagers); linkedFilesByClassName.put(className, linkedFiles); List<String> idsAttributes = new ArrayList<String>(); Class<?> c = Class.forName(className); Table tableAnn = c.getAnnotation(Table.class); if (tableAnn != null) { tableByClassName.put(className, tableAnn.name()); } else { Entity entityAnn = c.getAnnotation(Entity.class); if (entityAnn.name() != null) { tableByClassName.put(className, entityAnn.name()); } else { tableByClassName.put(className, className.substring(className.lastIndexOf(".") + 1)); } } BeanInfo beanInfo = Introspector.getBeanInfo(c); PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors(); propertyDescriptorsByClassName.put(className, pds); IdClass idClass = c.getAnnotation(IdClass.class); for (Field f : c.getDeclaredFields()) { Id id = f.getAnnotation(Id.class); if (id != null) { idsAttributes.add(f.getName()); if (f.isAnnotationPresent(GeneratedValue.class)) { generatedIdClasses.add(className); } } } if (!idsAttributes.isEmpty()) { for (Field f : c.getDeclaredFields()) { if (!Modifier.isStatic(f.getModifiers())) { PropertyDescriptor pd = getPropertyDescriptor(pds, f); processField(className, pd, ids, collections, lazys, eagers, f); } } if (idClass != null) { Class clazz = idClass.value(); for (Field f : clazz.getDeclaredFields()) { if (!Modifier.isStatic(f.getModifiers())) { PropertyDescriptor pd = getPropertyDescriptor(pds, f); processField(clazz.getName(), pd, ids, collections, lazys, eagers, f); } } } /*for(PropertyDescriptor pd : pds) { processLinkedFiles(pds, linkedFiles, pd); }*/ } else { for (PropertyDescriptor pd : pds) { processMethod(className, pds, ids, collections, lazys, eagers, linkedFiles, pd); } if (idClass != null) { Class clazz = idClass.value(); for (PropertyDescriptor pd : Introspector.getBeanInfo(clazz).getPropertyDescriptors()) { processMethod(clazz.getName(), pds, ids, collections, lazys, eagers, linkedFiles, pd); } } } return ids; } private static PropertyDescriptor getPropertyDescriptor(PropertyDescriptor[] pds, Field f) throws PersistenceException { PropertyDescriptor pd = null; for (PropertyDescriptor p : pds) { if (f.getName().equals(p.getName())) { pd = p; break; } } if (pd == null) throw new PersistenceException("PropertyDescriptor not found for " + f.getName() + " in class " + f.getDeclaringClass().getName()); return pd; } private static void processMethod(String className, PropertyDescriptor[] pds, Set<PropertyDescriptor> ids, Set<PropertyDescriptor> collections, Set<PropertyDescriptor> lazys, Set<PropertyDescriptor> eagers, Set<LinkFileInfo> linkedFiles, PropertyDescriptor pd) throws PersistenceException { Method readMethod = pd.getReadMethod(); if (readMethod != null) { if (readMethod.isAnnotationPresent(Id.class)) { ids.add(pd); if (readMethod.isAnnotationPresent(GeneratedValue.class)) { generatedIdClasses.add(className); } } OneToMany oneToMany = readMethod.getAnnotation(OneToMany.class); if (oneToMany != null) { collections.add(pd); } else { ManyToMany manyToMany = readMethod.getAnnotation(ManyToMany.class); if (manyToMany != null) { collections.add(pd); } else if (INakedObject.class.isAssignableFrom(pd.getPropertyType())) { OneToOne oneToOne = readMethod.getAnnotation(OneToOne.class); if (oneToOne != null) { if (oneToOne.fetch().equals(FetchType.LAZY)) lazys.add(pd); else eagers.add(pd); } else { ManyToOne manyToOne = readMethod.getAnnotation(ManyToOne.class); if (manyToOne != null) { if (manyToOne.fetch().equals(FetchType.LAZY)) lazys.add(pd); else eagers.add(pd); } else { Basic basic = readMethod.getAnnotation(Basic.class); if (basic != null) { if (basic.fetch().equals(FetchType.LAZY)) lazys.add(pd); else eagers.add(pd); } } } } } //processLinkedFiles(pds, linkedFiles, pd); } } /*private static void processLinkedFiles(PropertyDescriptor[] pds, Set<LinkFileInfo> linkedFiles, PropertyDescriptor pd) throws PersistenceException { Method readMethod = pd.getReadMethod(); if(readMethod != null) { UILinkedFile lfAnn = readMethod.getAnnotation(UILinkedFile.class); if(lfAnn != null) { if(pd.getWriteMethod() == null) { throw new PersistenceException("Missing setter for property "+pd.getName()+" with annotation "+UILinkedFile.class.getName()); } Method localFileIdGetter = null; for(PropertyDescriptor p : pds) { if(lfAnn.localKeyField().equals(p.getName())) { localFileIdGetter = p.getReadMethod(); break; } } if(localFileIdGetter == null) { throw new PersistenceException("Missing getter for property "+lfAnn.localKeyField()+" with annotation "+UILinkedFile.class.getName()); } linkedFiles.add(new LinkFileInfo(pd.getWriteMethod(), localFileIdGetter, lfAnn.fileClassName(), lfAnn.fileFieldName())); } } }*/ private static void processField(String className, PropertyDescriptor pd, Set<PropertyDescriptor> ids, Set<PropertyDescriptor> collections, Set<PropertyDescriptor> lazys, Set<PropertyDescriptor> eagers, Field f) { if (f.isAnnotationPresent(Id.class)) { ids.add(pd); if (f.isAnnotationPresent(GeneratedValue.class)) { generatedIdClasses.add(className); } } OneToMany oneToMany = f.getAnnotation(OneToMany.class); CollectionTable collTable = f.getAnnotation(CollectionTable.class); if (oneToMany != null || collTable != null) { collections.add(pd); } else { ManyToMany manyToMany = f.getAnnotation(ManyToMany.class); if (manyToMany != null) { collections.add(pd); } else if (INakedObject.class.isAssignableFrom(f.getType())) { OneToOne oneToOne = f.getAnnotation(OneToOne.class); if (oneToOne != null) { if (oneToOne.fetch().equals(FetchType.LAZY)) { lazys.add(pd); } else { eagers.add(pd); } } else { ManyToOne manyToOne = f.getAnnotation(ManyToOne.class); if (manyToOne != null) { if (manyToOne.fetch().equals(FetchType.LAZY)) { lazys.add(pd); } else { eagers.add(pd); } } else { Basic basic = f.getAnnotation(Basic.class); if (basic != null) { if (basic.fetch().equals(FetchType.LAZY)) { lazys.add(pd); } else { eagers.add(pd); } } } } } } } @Override public Collection<INakedObject> deproxyCollection(INakedObject no, String attributeName, EntityManager em, Map<String, Map<com.hiperf.common.ui.shared.util.Id, INakedObject>> deproxyContext) throws PersistenceException { try { String name = no.getClass().getName(); Set<PropertyDescriptor> colls = collectionsByClassName.get(name); if (colls != null && !colls.isEmpty()) { for (PropertyDescriptor pd : colls) { if (attributeName.equals(pd.getName())) { Method readMethod = pd.getReadMethod(); deproxyCollection(no, readMethod, pd.getWriteMethod(), (Collection) readMethod.invoke(no, new Object[0]), null, em, deproxyContext); return (Collection<INakedObject>) readMethod.invoke(no, new Object[0]); } } } return null; } catch (Exception e) { logger.log(Level.SEVERE, "Exception in deproxyCollection", e); throw new PersistenceException("Exception in deproxyCollection...", e); } } @Override public INakedObject deproxyLinkedObject(INakedObject no, String attributeName, EntityManager em) throws PersistenceException { try { String name = no.getClass().getName(); Set<PropertyDescriptor> colls = lazysByClassName.get(name); if (colls != null && !colls.isEmpty()) { INakedObject lo = deproxyLinkedObject(no, attributeName, colls, em); if (lo != null) return lo; } colls = eagerObjectsByClassName.get(name); if (colls != null && !colls.isEmpty()) { INakedObject lo = deproxyLinkedObject(no, attributeName, colls, em); if (lo != null) return lo; } return null; } catch (Exception e) { logger.log(Level.SEVERE, "Exception in deproxyLinkedObject", e); throw new PersistenceException("Exception in deproxyLinkedObject...", e); } } private INakedObject deproxyLinkedObject(INakedObject no, String attributeName, Set<PropertyDescriptor> colls, EntityManager em) throws IllegalAccessException, InvocationTargetException, InstantiationException, IntrospectionException, PersistenceException, ClassNotFoundException { for (PropertyDescriptor pd : colls) { if (attributeName.equals(pd.getName())) { Method readMethod = pd.getReadMethod(); INakedObject linkedObj = (INakedObject) readMethod.invoke(no, new Object[0]); return deproxyNakedObject(linkedObj, em, new HashMap<String, Map<com.hiperf.common.ui.shared.util.Id, INakedObject>>()); } } return null; } @Override public Object getCompositeId(Class<?> c, List<String> idFieldNames, List myId) throws InstantiationException, IllegalAccessException { IdClass idClass = c.getAnnotation(IdClass.class); Class clazz = idClass.value(); Object pk = clazz.newInstance(); for (Field f : clazz.getDeclaredFields()) { int idx = idFieldNames.indexOf(f.getName()); if (idx >= 0) { boolean b = false; if (!f.isAccessible()) { f.setAccessible(true); b = true; } f.set(pk, myId.get(idx)); if (b) f.setAccessible(false); } } return pk; } public static boolean isComposite(String className) throws PersistenceException { return idsByClassName.get(className).size() > 1; } public static String getTable(String className) throws PersistenceException { return tableByClassName.get(className); } @Override public void updateAttributeValue(String className, INakedObject original, String att, Object object) throws PersistenceException { for (PropertyDescriptor pd : propertyDescriptorsByClassName.get(className)) { if (pd.getName() != null && pd.getName().equals(att) && pd.getWriteMethod() != null) { try { pd.getWriteMethod().invoke(original, object); return; } catch (Exception e) { throw new PersistenceException(e); } } } } @Override public INakedObject get(String nakedObjectName, com.hiperf.common.ui.shared.util.Id id) throws PersistenceException { INakedObject o = null; EntityManager em = null; try { em = getEntityManager(); o = getObject(Class.forName(nakedObjectName), id, em); return deproxyNakedObject(o, em, new HashMap<String, Map<com.hiperf.common.ui.shared.util.Id, INakedObject>>()); } catch (Exception e) { logger.log(Level.SEVERE, "Exception in get : " + e.getMessage(), e); throw new PersistenceException("Exception in get : " + e.getMessage(), e); } finally { closeEntityManager(em); } } private INakedObject getObject(Class<?> clazz, com.hiperf.common.ui.shared.util.Id id, EntityManager em) throws ClassNotFoundException, InstantiationException, IllegalAccessException { INakedObject o; if (id.getFieldValues().size() == 1) { o = (INakedObject) em.find(clazz, id.getFieldValues().get(0)); } else { o = (INakedObject) em.find(clazz, getCompositeId(clazz, id.getFieldNames(), id.getFieldValues())); } return o; } @Override public Map<String, String> getAll(String rootClassName, String filter, String attPrefix, String childClassName, String childAttribute) throws PersistenceException { EntityManager em = null; if (attPrefix != null && !attPrefix.isEmpty()) { String[] s = attPrefix.split("\\."); if (s == null || s.length == 0) s = new String[] { attPrefix }; StringBuilder join = new StringBuilder(); StringBuilder select = new StringBuilder(); String lastClass = rootClassName; String lastJoinPrefix = "o."; int i = 0; for (int j = 0; j < s.length; j++) { String ss = s[j]; PropertyDescriptor[] pds = propertyDescriptorsByClassName.get(lastClass); for (PropertyDescriptor pd : pds) { if (pd.getName().equals(ss)) { Class<?> pt = pd.getPropertyType(); if (Collection.class.isAssignableFrom(pt) || INakedObject.class.isAssignableFrom(pt)) { join.append(" inner join ").append(lastJoinPrefix); if (!lastJoinPrefix.endsWith(".")) { join.append("."); } join.append(ss).append(" y").append(i).append(" "); lastJoinPrefix = "y" + i + "."; i++; if (Collection.class.isAssignableFrom(pt)) { Class<?> clazz; try { clazz = Class.forName(lastClass); ParameterizedType genericType = (ParameterizedType) clazz.getDeclaredField(ss) .getGenericType(); if (genericType != null) { for (Type t : genericType.getActualTypeArguments()) { if (t instanceof Class && INakedObject.class.isAssignableFrom((Class) t)) { lastClass = ((Class) t).getName(); break; } } } } catch (Exception e) { logger.log(Level.SEVERE, "Error", e); } } else { lastClass = pt.getName(); } } else if (childClassName.equals(pt.getName())) { lastJoinPrefix += ss + "."; if (i == s.length - 1) { select.append("select ").append(lastJoinPrefix).append(childAttribute) .append(" from ").append(rootClassName).append(" o "); } lastClass = pt.getName(); } else { lastJoinPrefix += ss + "."; lastClass = pt.getName(); } break; } } } HashMap<String, String> joinMap = null; if (join.length() > 0) { if (filter != null && !filter.isEmpty()) { int idx = filter.indexOf("inner join "); if (idx >= 0) { joinMap = new HashMap<>(); String[] ff = filter.substring(idx + 11, filter.indexOf("where")).trim() .split("inner join "); for (String fj : ff) { fj = fj.trim(); String[] fjj = fj.split(" "); if (fjj.length == 2) { joinMap.put(fjj[0].trim(), fjj[1].trim()); } } } } } if (joinMap != null && !joinMap.isEmpty() && join.length() > 0) { String jj = join.toString(); for (Entry<String, String> e : joinMap.entrySet()) { String tmp = "inner join " + e.getKey(); int k = jj.indexOf(tmp); if (k >= 0) { String ss = join.substring(k + tmp.length()).trim(); int m = ss.indexOf(" "); if (m > 0) { ss = ss.substring(0, m); } jj = jj.replace(ss, e.getValue()); /*lastJoinPrefix = lastJoinPrefix.replaceAll(ss, e.getValue()); join.replace(k, k + tmp.length() + 1 + ss.length(), "");*/ } } } if (select.length() == 0) { select.append("select ").append(lastJoinPrefix).append(childAttribute).append(" from ") .append(rootClassName).append(" o "); } if (join.length() > 0) { select.append(join); } if (filter != null && !filter.isEmpty()) { if (!filter.toLowerCase().contains("where")) select.append(" where "); select.append(filter); } select.append(" order by ").append(lastJoinPrefix).append(childAttribute).append(" asc"); String jpql = select.toString(); List<Date> dtParams = new ArrayList<Date>(); try { em = getEntityManager(); jpql = replaceDateParameters(jpql, dtParams); Query q = em.createQuery(jpql); List<Object> list = getResults(dtParams, q); if (list != null && !list.isEmpty()) { Map<String, String> map = new LinkedHashMap<String, String>(); for (Object o : list) { StorageHelper.fillGetAllMap(map, o); } return map; } else return null; } catch (Exception e) { logger.log(Level.SEVERE, "Exception in getAll " + e.getMessage(), e); throw new PersistenceException("Exception in getAll " + e.getMessage(), e); } finally { closeEntityManager(em); } } else { try { em = getEntityManager(); String jql = "select distinct o."; jql += childAttribute + " from " + rootClassName + " o "; if (filter != null && !filter.isEmpty()) { jql += filter; } jql += " order by o." + childAttribute + " asc"; List<Date> dtParams = new ArrayList<Date>(); jql = replaceDateParameters(jql, dtParams); Query q = em.createQuery(jql); List<Object> list = getResults(dtParams, q); if (list != null && !list.isEmpty()) { Map<String, String> map = new LinkedHashMap<String, String>(); for (Object o : list) { StorageHelper.fillGetAllMap(map, o); } return map; } else return null; } catch (Exception e) { logger.log(Level.SEVERE, "Exception in getAll " + e.getMessage(), e); throw new PersistenceException("Exception in getAll " + e.getMessage(), e); } finally { closeEntityManager(em); } } } private List<Object> getResults(List<Date> dtParams, Query q) { if (!dtParams.isEmpty()) { for (int k = 0; k < dtParams.size(); k++) { q.setParameter("dt" + k, dtParams.get(k)); } } List<Object> list = q.getResultList(); return list; } @Override public Filter getFilter(Long id) throws PersistenceException { Filter f = null; EntityManager em = null; try { em = getEntityManager(); f = em.find(Filter.class, id); if (f != null && f.getValues() != null && !f.getValues().isEmpty()) { List<FilterValue> l = new ArrayList<FilterValue>(f.getValues().size()); for (FilterValue fv : f.getValues()) l.add(fv); f.setValues(l); } return f; } catch (Exception e) { logger.log(Level.SEVERE, "Exception in getFilter " + e.getMessage(), e); throw new PersistenceException("Exception in getFilter " + e.getMessage(), e); } finally { closeEntityManager(em); } } @Override public Collection<INakedObject> getCollection(String nakedObjectName, com.hiperf.common.ui.shared.util.Id id, String attributeName) throws PersistenceException { INakedObject o = null; EntityManager em = null; try { em = getEntityManager(); Map<String, Map<com.hiperf.common.ui.shared.util.Id, INakedObject>> deproxyContext = new HashMap<String, Map<com.hiperf.common.ui.shared.util.Id, INakedObject>>(); if (id.getFieldNames().size() == 1) { o = (INakedObject) em.find(Class.forName(nakedObjectName), id.getFieldValues().get(0)); } else { Class c = Class.forName(nakedObjectName); o = (INakedObject) em.find(c, getCompositeId(c, id.getFieldNames(), id.getFieldValues())); } if (o != null) { return deproxyCollection(o, attributeName, em, deproxyContext); } return null; } catch (Exception e) { logger.log(Level.SEVERE, "Exception in getCollection " + e.getMessage(), e); throw new PersistenceException("Exception in getCollection " + e.getMessage(), e); } finally { closeEntityManager(em); } } @Override public Map<Long, String> getFilters(String viewName, final String className, String userName) throws PersistenceException { EntityManager em = null; try { em = getEntityManager(); String hql = "select o.id, o.name from Filter o where o.userName = :usr and o.className = :clazz"; if (viewName != null) hql += " and o.viewName = :view"; Query q = em.createQuery(hql); q.setParameter("usr", userName).setParameter("clazz", className); if (viewName != null) q.setParameter("view", viewName); List<Object[]> l = q.getResultList(); if (l != null && !l.isEmpty()) { Map<Long, String> map = new HashMap<Long, String>(l.size()); for (Object[] o : l) { map.put((Long) o[0], (String) o[1]); } return map; } return null; } catch (Exception e) { logger.log(Level.SEVERE, "Exception in getCollection " + e.getMessage(), e); throw new PersistenceException("Exception in getCollection " + e.getMessage(), e); } finally { closeEntityManager(em); } } @Override public List<INakedObject> getAll(String jpqlQuery) throws PersistenceException { EntityManager em = null; List<INakedObject> res = null; try { em = getEntityManager(); Query q = em.createQuery(jpqlQuery); setQueryTimeout(q); List<INakedObject> l = q.getResultList(); if (l != null && !l.isEmpty()) { Map<String, Map<com.hiperf.common.ui.shared.util.Id, INakedObject>> deproxyContext = new HashMap<String, Map<com.hiperf.common.ui.shared.util.Id, INakedObject>>(); res = new ArrayList<>(l.size()); for (INakedObject no : l) { res.add(deproxyNakedObject(no, em, deproxyContext)); } } return res; } catch (Exception e) { logger.log(Level.SEVERE, "Exception in getAll " + e.getMessage(), e); throw new PersistenceException("Exception in getAll " + e.getMessage(), e); } finally { closeEntityManager(em); } } @Override public NakedObjectsList queryData(String className, String currentFilter, int page, int rowsPerPage, String orderBy, ObjectsToPersist toPersist, Locale locale, boolean distinct) throws PersistenceException { TransactionContext tc = null; Map<com.hiperf.common.ui.shared.util.Id, INakedObject> res = new HashMap<com.hiperf.common.ui.shared.util.Id, INakedObject>(); try { Map<Object, IdHolder> newIdByOldId = new HashMap<Object, IdHolder>(); tc = createTransactionalContext(); EntityManager em = tc.getEm(); ITransaction tx = tc.getTx(); tx.begin(); if (toPersist != null) doPersist(toPersist, null, res, newIdByOldId, em, true, locale); Long count = null; int lastTotal = -1; StringBuilder jpqlSb; String jpql; List<Date> dtParams; if (rowsPerPage > 0) { jpqlSb = new StringBuilder("select count("); if (distinct && !isComposite(className)) jpqlSb.append("distinct "); jpqlSb.append("o) from ").append(className); jpql = appendWhereClause(currentFilter, jpqlSb.toString()); dtParams = new ArrayList<Date>(); jpql = replaceDateParameters(jpql, dtParams); Query countQuery = em.createQuery(jpql); if (!dtParams.isEmpty()) { for (int i = 0; i < dtParams.size(); i++) { countQuery.setParameter("dt" + i, dtParams.get(i)); } } count = (Long) countQuery.getResultList().get(0); lastTotal = rowsPerPage * (page - 1); } if (rowsPerPage <= 0 || (count > 0 && count > lastTotal)) { jpqlSb = new StringBuilder("select "); if (distinct) jpqlSb.append("distinct "); Set<PropertyDescriptor> ids = idsByClassName.get(className); Iterator<PropertyDescriptor> it = ids.iterator(); List<String> idFieldNames = new ArrayList<>(ids.size()); boolean hasOrder = orderBy != null && orderBy.length() > 0; while (it.hasNext()) { PropertyDescriptor n = it.next(); jpqlSb.append("o.").append(n.getName()); if (it.hasNext()) jpqlSb.append(","); if (!it.hasNext() && hasOrder) { jpqlSb.append(",").append(getOrderByClause(orderBy)); } idFieldNames.add(n.getName()); } jpqlSb.append(" from ").append(className); jpql = appendWhereClause(currentFilter, jpqlSb.toString()); dtParams = new ArrayList<Date>(); jpql = replaceDateParameters(jpql, dtParams); Query q = getSelectQuery(rowsPerPage, orderBy, em, jpql, dtParams, lastTotal, idFieldNames); List<INakedObject> list = null; try { list = fillResultList(className, em, ids, idFieldNames, q, hasOrder); } catch (Exception e) { e.printStackTrace(); if (e.getMessage().contains("ORA-01791")) { int idx = orderBy.indexOf("@"); if (idx > 0) { String s = orderBy.substring("left outer join ".length()).trim(); String clause = orderBy.substring(idx + 1); orderBy = " order by " + s.substring(0, s.indexOf(" ")); StringTokenizer st = new StringTokenizer(clause); boolean asc = true; while (st.hasMoreTokens()) { String tok = st.nextToken(); if (tok.equals(",")) break; if (tok.equalsIgnoreCase("desc")) { asc = false; break; } } if (!asc) { orderBy += " DESC"; } } else { idx = orderBy.indexOf(","); if (idx > 0) orderBy = orderBy.substring(0, idx).trim(); idx = orderBy.indexOf("left outer join "); idx = orderBy.indexOf("."); if (idx > 0) orderBy = orderBy.substring(0, idx).trim(); } q = getSelectQuery(rowsPerPage, orderBy, em, jpql, dtParams, lastTotal, idFieldNames); list = fillResultList(className, em, ids, idFieldNames, q, hasOrder); } else throw e; } Map<String, Map<Object, Object>> oldIdByNewId = buildInverseIdMap(newIdByOldId); if (list != null && !list.isEmpty()) { list = deproxyEntities(className, list, true, oldIdByNewId); } return new NakedObjectsList(list, count != null ? count.intValue() : list != null ? list.size() : 0, rowsPerPage, currentFilter); } else return null; } catch (Exception e) { logger.log(Level.SEVERE, "Exception in queryData : " + e.getMessage(), e); throw new PersistenceException(e.getMessage(), e); } finally { finalizeTx(tc); } } public String getOrderByClause(String orderBy) { String l = orderBy.toLowerCase(); int i = l.indexOf("by"); if (i >= 0) orderBy = orderBy.substring(i + 2); if (l.endsWith("desc")) { orderBy = orderBy.substring(0, orderBy.length() - 4); } else if (l.endsWith("asc")) orderBy = orderBy.substring(0, orderBy.length() - 3); return orderBy; } public List<INakedObject> fillResultList(String className, EntityManager em, Set<PropertyDescriptor> ids, List<String> idFieldNames, Query q, boolean hasOrder) throws ClassNotFoundException, InstantiationException, IllegalAccessException { q.setHint("org.hibernate.readOnly", Boolean.TRUE); List<Object[]> ll = q.getResultList(); if (ll != null && !ll.isEmpty()) { boolean single = ids.size() == 1; Object pk = null; Class<?> c = Class.forName(className); Class clazz = null; if (!single) { IdClass idClass = c.getAnnotation(IdClass.class); clazz = idClass.value(); pk = clazz.newInstance(); } List<INakedObject> list = new ArrayList<>(ll.size()); for (Object o : ll) { if (single) { list.add((INakedObject) em.find(c, hasOrder ? ((Object[]) o)[0] : o)); } else { for (Field f : clazz.getDeclaredFields()) { int idx = idFieldNames.indexOf(f.getName()); if (idx >= 0) { boolean b = false; if (!f.isAccessible()) { f.setAccessible(true); b = true; } f.set(pk, ((Object[]) o)[idx]); if (b) f.setAccessible(false); } } list.add((INakedObject) em.find(c, pk)); } } return list; } return null; } public Query getSelectQuery(int rowsPerPage, String orderBy, EntityManager em, String jpql, List<Date> dtParams, int lastTotal, List<String> idFieldNames) { if (orderBy != null && orderBy.length() > 0) { int join = orderBy.indexOf("@"); if (join > 0) { int k = jpql.indexOf("where"); if (k > 0) { jpql = jpql.substring(0, k) + orderBy.substring(0, join) + jpql.substring(k) + orderBy.substring(join + 1); } else { jpql = jpql + " " + orderBy.substring(0, join) + orderBy.substring(join + 1); } } else jpql = jpql + " " + orderBy; jpql = jpql + ", " + toString(idFieldNames); } Query q = em.createQuery(jpql); if (!dtParams.isEmpty()) { for (int i = 0; i < dtParams.size(); i++) { q.setParameter("dt" + i, dtParams.get(i)); } } setQueryTimeout(q); if (lastTotal >= 0 && rowsPerPage > 0) { q.setFirstResult(lastTotal); q.setMaxResults(rowsPerPage); } return q; } private void setQueryTimeout(Query q) { q.setHint("org.hibernate.timeout", new Integer(60)); } public static String toString(Collection collection) { StringBuilder sb = new StringBuilder("o."); Iterator it = collection.iterator(); while (it.hasNext()) { sb.append(it.next()); if (it.hasNext()) sb.append(", o."); } sb.append(" "); return sb.toString(); } private String replaceDateParameters(String jpql, List<Date> dtParams) throws ParseException { if (jpql.contains(IConstants.DT_SEP)) { String[] split = jpql.split(IConstants.DT_SEP); int j = 0; SimpleDateFormat sdf = new SimpleDateFormat(IConstants.DT_YYYY_MM_DD); for (int i = 1; i < split.length; i++) { if (split[i] != null && split[i].length() > 0 && !split[i].startsWith(" ")) { try { Date dt = sdf.parse(split[i]); String last = split[i - 1].trim(); if (last.endsWith("<") || last.endsWith("<=")) { dt.setHours(23); dt.setMinutes(59); dt.setSeconds(59); } else if (last.endsWith(">") || last.endsWith(">=")) { dt.setHours(0); dt.setMinutes(0); dt.setSeconds(0); } dtParams.add(dt); split[i] = ":dt" + j; j++; } catch (Exception e) { } } } jpql = ""; for (int i = 0; i < split.length; i++) { jpql = jpql + split[i]; } } return jpql; } @Override public NakedObjectsList queryData(String className, String currentFilter, int page, int rowsPerPage, String orderBy, ObjectsToPersist toPersist, Locale locale) throws PersistenceException { return queryData(className, currentFilter, page, rowsPerPage, orderBy, toPersist, locale, false); } private String appendWhereClause(String currentFilter, String jpql) { if (currentFilter != null && currentFilter.length() > 0) { if (currentFilter.startsWith("o.") || currentFilter.startsWith("(o.") || currentFilter.startsWith("UPPER(o.")) { jpql += " o where " + currentFilter; } else { jpql += " o " + currentFilter; } } else { jpql += " o"; } return jpql; } @Override public Map<com.hiperf.common.ui.shared.util.Id, INakedObject> persist(ObjectsToPersist toPersist, String userName, Locale locale) throws PersistenceException { TransactionContext tc = null; Map<com.hiperf.common.ui.shared.util.Id, INakedObject> res = new HashMap<com.hiperf.common.ui.shared.util.Id, INakedObject>(); try { Map<Object, IdHolder> newIdByOldId = new HashMap<Object, IdHolder>(); tc = createTransactionalContext(); EntityManager em = tc.getEm(); ITransaction tx = tc.getTx(); tx.begin(); if (doPersist(toPersist, userName, res, newIdByOldId, em, false, locale)) tx.commit(); else throw new PersistenceException("a technical problem occured during data insertion"); } catch (Exception e) { catchPersistException(tc, e); processDbExceptions(locale, e); } finally { if (tc != null) close(tc); } Map<String, Map<com.hiperf.common.ui.shared.util.Id, INakedObject>> deproxyCtx = new HashMap<String, Map<com.hiperf.common.ui.shared.util.Id, INakedObject>>(); EntityManager em = null; try { for (Entry<com.hiperf.common.ui.shared.util.Id, INakedObject> entry : res.entrySet()) { em = getEntityManager(); INakedObject no = entry.getValue(); String nakedObjectName = no.getClass().getName(); com.hiperf.common.ui.shared.util.Id id = getId(no, idsByClassName.get(nakedObjectName)); Map<com.hiperf.common.ui.shared.util.Id, INakedObject> map = deproxyCtx.get(nakedObjectName); if (map == null || !map.containsKey(id)) { if (id.getFieldNames().size() == 1) { no = (INakedObject) em.find(Class.forName(nakedObjectName), id.getFieldValues().get(0)); } else { Class c = Class.forName(nakedObjectName); no = (INakedObject) em.find(c, getCompositeId(c, id.getFieldNames(), id.getFieldValues())); } entry.setValue(deproxyNakedObject(no, em, deproxyCtx)); } else { entry.setValue(map.get(id)); } } return res; } catch (Exception e) { logger.log(Level.SEVERE, "Exception in persist : " + e.getMessage(), e); throw new PersistenceException("Exception in persist : " + e.getMessage(), e); } finally { closeEntityManager(em); } } private void closeEntityManager(EntityManager em) { if (em != null && em.isOpen()) close(em); } @Override public boolean doPersist(ObjectsToPersist toPersist, Map<com.hiperf.common.ui.shared.util.Id, INakedObject> res, Map<Object, IdHolder> newIdByOldId, EntityManager em, Locale locale) throws ClassNotFoundException, IntrospectionException, PersistenceException, IllegalAccessException, InvocationTargetException, InstantiationException { return doPersist(toPersist, null, res, newIdByOldId, em, true, locale, false); } private boolean doPersist(ObjectsToPersist toPersist, String userName, Map<com.hiperf.common.ui.shared.util.Id, INakedObject> res, Map<Object, IdHolder> newIdByOldId, EntityManager em, boolean validateBefore, Locale locale) throws ClassNotFoundException, IntrospectionException, PersistenceException, IllegalAccessException, InvocationTargetException, InstantiationException { return doPersist(toPersist, userName, res, newIdByOldId, em, validateBefore, locale, true); } private boolean doPersist(ObjectsToPersist toPersist, String userName, Map<com.hiperf.common.ui.shared.util.Id, INakedObject> res, Map<Object, IdHolder> newIdByOldId, EntityManager em, boolean validateBefore, Locale locale, boolean processExceptions) throws ClassNotFoundException, IntrospectionException, PersistenceException, IllegalAccessException, InvocationTargetException, InstantiationException { try { Validator validator = validatorFactory.getValidator(); List<INakedObject> toInsert = toPersist.getInsertedObjects(); if (toInsert != null) { int max = 100 * toInsert.size(); int idx = -1; int k = -1; int s = toInsert.size(); int prevSize = s; while (!toInsert.isEmpty()) { if (s == toInsert.size()) { k++; } else k = 0; if (k == 1) { logger.log(Level.FINE, "Impossible to persist data : one linked object not found in toInsert list"); return false; } if (prevSize == toInsert.size()) { idx++; } else { idx = 0; prevSize = toInsert.size(); } if (idx > max) { logger.log(Level.FINE, "Impossible to persist data : one linked object not found in toInsert list..."); return false; } Iterator<INakedObject> it = toInsert.iterator(); while (it.hasNext()) { INakedObject o = (INakedObject) it.next(); String className = o.getClass().getName(); if (o instanceof IAuditable) { IAuditable aud = (IAuditable) o; aud.setCreateUser(userName); aud.setCreateDate(new Date()); } Set<PropertyDescriptor> ids = idsByClassName.get(className); processLinkedCollectionsBeforePersist(o, collectionsByClassName.get(className)); if (!processLinkedObjectsBeforePersist(newIdByOldId, o, lazysByClassName.get(className), toPersist)) continue; if (!processLinkedObjectsBeforePersist(newIdByOldId, o, eagerObjectsByClassName.get(className), toPersist)) continue; if (generatedIdClasses.contains(className)) { PropertyDescriptor idPd = ids.iterator().next(); Object oldId = idPd.getReadMethod().invoke(o, StorageService.emptyArg); Object[] args = new Object[1]; if (!idPd.getPropertyType().isPrimitive()) args[0] = null; else args[0] = 0L; idPd.getWriteMethod().invoke(o, args); if (validateBefore) { Set<ConstraintViolation<INakedObject>> errors = validator.validate(o); if (errors != null && !errors.isEmpty()) { it.remove(); continue; } try { em.persist(o); } catch (Exception e) { it.remove(); continue; } } else em.persist(o); Object newId = idPd.getReadMethod().invoke(o, StorageService.emptyArg); newIdByOldId.put(oldId, new IdHolder(newId, className)); List<Object> idVals = new ArrayList<Object>(1); idVals.add(oldId); List<String> idFields = new ArrayList<String>(1); idFields.add(idPd.getName()); res.put(new com.hiperf.common.ui.shared.util.Id(idFields, idVals), o); it.remove(); } else { com.hiperf.common.ui.shared.util.Id id = getId(o, ids); int i = 0; boolean toProcess = true; for (Object idVal : id.getFieldValues()) { if ((idVal instanceof Long && ((Long) idVal).longValue() < 0) || (idVal instanceof String && ((String) idVal).startsWith(PersistenceManager.SEQ_PREFIX))) { IdHolder newIds = newIdByOldId.get(idVal); if (newIds != null) { String att = id.getFieldNames().get(i); for (PropertyDescriptor idPd : ids) { if (idPd.getName().equals(att)) { Object[] args = new Object[1]; args[0] = newIds.getId(); idPd.getWriteMethod().invoke(o, args); break; } } } else { toProcess = false; break; } } i++; } if (toProcess) { if (validateBefore) { Set<ConstraintViolation<INakedObject>> errors = validator.validate(o); if (errors != null && !errors.isEmpty()) { it.remove(); continue; } try { refreshManyToOneLinkedWithId(o, id, em); em.persist(o); } catch (Exception e) { it.remove(); continue; } } else { refreshManyToOneLinkedWithId(o, id, em); em.persist(o); } id = getId(o, ids); res.put(id, o); it.remove(); } } } } } Map<String, Set<com.hiperf.common.ui.shared.util.Id>> toDelete = toPersist .getRemovedObjectsIdsByClassName(); if (toDelete != null) { for (String className : toDelete.keySet()) { Set<com.hiperf.common.ui.shared.util.Id> ids = toDelete.get(className); Class<?> clazz = Class.forName(className); Map<Field, Field> toRemove = null; if (ids != null && !ids.isEmpty()) { com.hiperf.common.ui.shared.util.Id id = ids.iterator().next(); if (id.getFieldValues().size() > 1) { toRemove = new HashMap<Field, Field>(); Field[] fields = clazz.getDeclaredFields(); for (Field f : fields) { if (f.isAnnotationPresent(ManyToOne.class)) { Field[] ff = f.getType().getDeclaredFields(); for (Field lf : ff) { OneToMany ann = lf.getAnnotation(OneToMany.class); if (ann != null && ann.targetEntity() != null && ann.targetEntity().equals(clazz)) { toRemove.put(f, lf); } } } } // TODO : manage annotations on the getters... } } for (com.hiperf.common.ui.shared.util.Id id : ids) { INakedObject no = getObject(clazz, id, em); if (no != null) { if (toRemove != null && !toRemove.isEmpty()) { for (Entry<Field, Field> e : toRemove.entrySet()) { Field f = e.getKey(); Field ff = e.getValue(); boolean b1 = false; boolean b2 = false; if (!f.isAccessible()) { f.setAccessible(true); b1 = true; } if (!ff.isAccessible()) { ff.setAccessible(true); b2 = true; } ((Collection) ff.get(f.get(no))).remove(no); if (b1) f.setAccessible(false); if (b2) ff.setAccessible(false); } } else { // TODO : manage annotations on the getters... } em.remove(no); } } } } Map<String, Map<com.hiperf.common.ui.shared.util.Id, Map<String, Serializable>>> toUpdate = toPersist .getUpdatedObjects(); if (toUpdate != null) { for (String className : toUpdate.keySet()) { Map<com.hiperf.common.ui.shared.util.Id, Map<String, Serializable>> map = toUpdate .get(className); Class<?> clazz = Class.forName(className); Iterator<Entry<com.hiperf.common.ui.shared.util.Id, Map<String, Serializable>>> iterator = map .entrySet().iterator(); while (iterator.hasNext()) { Entry<com.hiperf.common.ui.shared.util.Id, Map<String, Serializable>> entry = iterator .next(); com.hiperf.common.ui.shared.util.Id id = entry.getKey(); INakedObject original = getObject(clazz, id, em); Map<String, Serializable> updateMap = entry.getValue(); for (String att : updateMap.keySet()) { Object object = updateMap.get(att); if (object != null && object instanceof NakedObjectHandler) { NakedObjectHandler oo = (NakedObjectHandler) object; com.hiperf.common.ui.shared.util.Id objId = oo.getId(); if (generatedIdClasses.contains(oo.getClassName()) && newIdByOldId.containsKey(objId.getFieldValues().get(0))) { IdHolder newIds = newIdByOldId.get(objId.getFieldValues().get(0)); List<Object> idVals = new ArrayList<Object>(1); idVals.add(newIds.getId()); List<String> idFields = new ArrayList<String>(1); idFields.add(idsByClassName.get(oo.getClassName()).iterator().next().getName()); com.hiperf.common.ui.shared.util.Id newObjId = new com.hiperf.common.ui.shared.util.Id( idFields, idVals); object = getObject(Class.forName(oo.getClassName()), newObjId, em); } else { object = getObject(Class.forName(oo.getClassName()), oo.getId(), em); } } updateAttributeValue(className, original, att, object); } if (original instanceof IAuditable) { IAuditable aud = (IAuditable) original; aud.setModifyUser(userName); aud.setModifyDate(new Date()); } INakedObject o = null; if (validateBefore) { Set<ConstraintViolation<INakedObject>> errors = validator.validate(original); if (errors != null && !errors.isEmpty()) { iterator.remove(); continue; } try { o = em.merge(original); em.flush(); } catch (Exception e) { iterator.remove(); continue; } } else o = em.merge(original); res.put(id, o); } } } processAddedManyToMany(toPersist, res, newIdByOldId, em); processRemovedManyToMany(toPersist, res, newIdByOldId, em); em.flush(); return true; } catch (Exception e) { logger.log(Level.WARNING, "Exception", e); if (processExceptions) { processDbExceptions(locale, e); return false; } else throw new PersistenceException(e); } } private void refreshManyToOneLinkedWithId(INakedObject o, com.hiperf.common.ui.shared.util.Id id, EntityManager em) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { Class<? extends INakedObject> clazz = o.getClass(); Field f = clazz.getDeclaredField(id.getFieldNames().get(0)); if (f.isAnnotationPresent(Id.class)) { int i = 0; for (String name : id.getFieldNames()) { f = clazz.getDeclaredField(id.getFieldNames().get(i)); String columnName = name; if (f.isAnnotationPresent(Column.class)) { columnName = f.getAnnotation(Column.class).name(); } for (Field field : clazz.getDeclaredFields()) { if (field.isAnnotationPresent(ManyToOne.class) && field.isAnnotationPresent(JoinColumn.class) && field.getAnnotation(JoinColumn.class).name().equalsIgnoreCase(columnName)) { boolean acc = field.isAccessible(); try { if (!acc) field.setAccessible(true); Object pk = id.getFieldValues().get(i); if (PersistenceManager.isLocal(pk)) { boolean acc2 = f.isAccessible(); try { if (!acc2) { f.setAccessible(true); } pk = f.get(o); } finally { if (!acc2) { f.setAccessible(false); } } if (!PersistenceManager.isLocal(pk)) field.set(o, em.find(field.getType(), pk)); } else field.set(o, em.find(field.getType(), pk)); } finally { field.setAccessible(acc); } break; } } i++; } } else { //TODO } } private void processRemovedManyToMany(ObjectsToPersist toPersist, Map<com.hiperf.common.ui.shared.util.Id, INakedObject> res, Map<Object, IdHolder> newIdByOldId, EntityManager em) throws ClassNotFoundException, IntrospectionException, PersistenceException, IllegalAccessException, InvocationTargetException, NoSuchFieldException { Map<String, Map<com.hiperf.common.ui.shared.util.Id, Map<String, List<com.hiperf.common.ui.shared.util.Id>>>> manyToManyRemoved = toPersist .getManyToManyRemovedByClassName(); if (manyToManyRemoved != null && !manyToManyRemoved.isEmpty()) { for (Entry<String, Map<com.hiperf.common.ui.shared.util.Id, Map<String, List<com.hiperf.common.ui.shared.util.Id>>>> e : manyToManyRemoved .entrySet()) { String className = e.getKey(); Map<com.hiperf.common.ui.shared.util.Id, Map<String, List<com.hiperf.common.ui.shared.util.Id>>> map = e .getValue(); if (map != null && !map.isEmpty()) { Class<?> clazz = Class.forName(className); for (Entry<com.hiperf.common.ui.shared.util.Id, Map<String, List<com.hiperf.common.ui.shared.util.Id>>> entry : map .entrySet()) { com.hiperf.common.ui.shared.util.Id id = entry.getKey(); Map<String, List<com.hiperf.common.ui.shared.util.Id>> m = entry.getValue(); if (m != null && !m.isEmpty()) { Object objId = id.getFieldValues().get(0); if (newIdByOldId.containsKey(objId)) objId = newIdByOldId.get(objId).getId(); Object o = em.find(clazz, objId); if (o != null) { PropertyDescriptor[] pds = propertyDescriptorsByClassName.get(className); for (Entry<String, List<com.hiperf.common.ui.shared.util.Id>> ee : m.entrySet()) { String attr = ee.getKey(); List<com.hiperf.common.ui.shared.util.Id> ll = ee.getValue(); if (ll != null && !ll.isEmpty()) { Collection coll = null; Class classInColl = null; PropertyDescriptor myPd = null; for (PropertyDescriptor pd : pds) { if (pd.getName().equals(attr)) { myPd = pd; coll = (Collection) pd.getReadMethod().invoke(o, StorageService.emptyArg); break; } } if (coll != null) { ParameterizedType genericType = (ParameterizedType) clazz .getDeclaredField(myPd.getName()).getGenericType(); if (genericType != null) { for (Type t : genericType.getActualTypeArguments()) { if (t instanceof Class && INakedObject.class.isAssignableFrom((Class) t)) { classInColl = (Class) t; break; } } } for (com.hiperf.common.ui.shared.util.Id i : ll) { Object idObj = i.getFieldValues().get(0); if (newIdByOldId.containsKey(idObj)) idObj = newIdByOldId.get(idObj); Object linkedObj = em.find(classInColl, idObj); coll.remove(linkedObj); } } } } res.put(id, (INakedObject) em.merge(o)); } } } } } } } private void processAddedManyToMany(ObjectsToPersist toPersist, Map<com.hiperf.common.ui.shared.util.Id, INakedObject> res, Map<Object, IdHolder> newIdByOldId, EntityManager em) throws ClassNotFoundException, IntrospectionException, PersistenceException, IllegalAccessException, InvocationTargetException, NoSuchFieldException { Map<String, Map<com.hiperf.common.ui.shared.util.Id, Map<String, List<com.hiperf.common.ui.shared.util.Id>>>> manyToManyAdded = toPersist .getManyToManyAddedByClassName(); if (manyToManyAdded != null && !manyToManyAdded.isEmpty()) { for (Entry<String, Map<com.hiperf.common.ui.shared.util.Id, Map<String, List<com.hiperf.common.ui.shared.util.Id>>>> e : manyToManyAdded .entrySet()) { String className = e.getKey(); Map<com.hiperf.common.ui.shared.util.Id, Map<String, List<com.hiperf.common.ui.shared.util.Id>>> map = e .getValue(); if (map != null && !map.isEmpty()) { Class<?> clazz = Class.forName(className); for (Entry<com.hiperf.common.ui.shared.util.Id, Map<String, List<com.hiperf.common.ui.shared.util.Id>>> entry : map .entrySet()) { com.hiperf.common.ui.shared.util.Id id = entry.getKey(); Map<String, List<com.hiperf.common.ui.shared.util.Id>> m = entry.getValue(); if (m != null && !m.isEmpty()) { Object objId = id.getFieldValues().get(0); if (newIdByOldId.containsKey(objId)) objId = newIdByOldId.get(objId).getId(); Object o = em.find(clazz, objId); if (o != null) { PropertyDescriptor[] pds = propertyDescriptorsByClassName.get(className); for (Entry<String, List<com.hiperf.common.ui.shared.util.Id>> ee : m.entrySet()) { String attr = ee.getKey(); List<com.hiperf.common.ui.shared.util.Id> ll = ee.getValue(); if (ll != null && !ll.isEmpty()) { Collection coll = null; Class classInColl = null; PropertyDescriptor myPd = null; String mappedBy = null; for (PropertyDescriptor pd : pds) { if (pd.getName().equals(attr)) { myPd = pd; coll = (Collection) pd.getReadMethod().invoke(o, StorageService.emptyArg); if (coll == null) { if (List.class.isAssignableFrom(pd.getPropertyType())) coll = new ArrayList(); else coll = new HashSet(); pd.getWriteMethod().invoke(o, coll); } ManyToMany ann = pd.getReadMethod().getAnnotation(ManyToMany.class); if (ann == null) { ann = clazz.getDeclaredField(pd.getName()) .getAnnotation(ManyToMany.class); } if (ann != null) { mappedBy = ann.mappedBy(); } break; } } if (coll != null) { ParameterizedType genericType = (ParameterizedType) clazz .getDeclaredField(myPd.getName()).getGenericType(); if (genericType != null) { for (Type t : genericType.getActualTypeArguments()) { if (t instanceof Class && INakedObject.class.isAssignableFrom((Class) t)) { classInColl = (Class) t; break; } } } for (com.hiperf.common.ui.shared.util.Id i : ll) { Object idObj = i.getFieldValues().get(0); if (newIdByOldId.containsKey(idObj)) idObj = newIdByOldId.get(idObj).getId(); Object linkedObj = em.find(classInColl, idObj); if (mappedBy == null || mappedBy.length() == 0) coll.add(linkedObj); else { PropertyDescriptor[] pds2 = propertyDescriptorsByClassName .get(classInColl.getName()); if (pds2 == null) { pds2 = propertyDescriptorsByClassName .get(classInColl.getName()); } for (PropertyDescriptor pd : collectionsByClassName .get(classInColl.getName())) { if (pd.getName().equals(mappedBy)) { Collection coll2 = (Collection) pd.getReadMethod() .invoke(linkedObj, StorageService.emptyArg); if (coll2 == null) { if (List.class .isAssignableFrom(pd.getPropertyType())) coll2 = new ArrayList(); else coll2 = new HashSet(); pd.getWriteMethod().invoke(linkedObj, coll2); } coll2.add(o); } } em.merge(linkedObj); } if (linkedObj instanceof INakedObject) res.put(i, (INakedObject) linkedObj); } } } } res.put(id, (INakedObject) em.merge(o)); } } } } } } } private void processDbExceptions(Locale locale, Throwable e) throws PersistenceException { Throwable t = e; while (t != null && !t.getClass().getName().contains("ConstraintViolationException")) { t = t.getCause(); } if (t != null) { ResourceBundle ressource = ResourceBundle.getBundle(SERVER_MESSAGES, locale, PersistenceHelper.class.getClassLoader(), new UTF8Control()); throw new PersistenceException(ressource.getString("errorConstraintViolation"), t); } else { logger.log(Level.SEVERE, "DB error", e); throw new PersistenceException(e); } } private void processLinkedCollectionsBeforePersist(INakedObject o, Set<PropertyDescriptor> linkedObjects) throws IllegalAccessException, InvocationTargetException, ClassNotFoundException, IntrospectionException, PersistenceException { if (linkedObjects != null && !linkedObjects.isEmpty()) { for (PropertyDescriptor pd : linkedObjects) { pd.getWriteMethod().invoke(o, nullArg); } } } private boolean processLinkedObjectsBeforePersist(Map<Object, IdHolder> newIdByOldId, INakedObject o, Set<PropertyDescriptor> linkedObjects, ObjectsToPersist toPersist) throws IllegalAccessException, InvocationTargetException, ClassNotFoundException, IntrospectionException, PersistenceException, InstantiationException { if (linkedObjects != null && !linkedObjects.isEmpty()) { for (PropertyDescriptor pd : linkedObjects) { INakedObject no = (INakedObject) pd.getReadMethod().invoke(o, StorageService.emptyArg); if (no != null) { Class<? extends INakedObject> linkedClass = no.getClass(); String linkedClassName = linkedClass.getName(); Set<PropertyDescriptor> loIds = idsByClassName.get(linkedClassName); com.hiperf.common.ui.shared.util.Id loId = getId(no, loIds); if (loId.isLocal()) { INakedObject newObj = linkedClass.newInstance(); int i = 0; for (Object id : loId.getFieldValues()) { if ((id instanceof Long && ((Long) id).longValue() < 0) || (id instanceof String && ((String) id).startsWith(PersistenceManager.SEQ_PREFIX))) { IdHolder ids = newIdByOldId.get(id); if (ids == null) return false; else id = ids.getId(); } setIdField(loIds, loId, newObj, i, id); i++; } setObject(o, pd, newObj); } else if (!newIdByOldId .containsValue(new IdHolder(loId.getFieldValues().get(0), linkedClassName)) && toPersist.getUpdatedObjects() != null && toPersist.getUpdatedObjects().containsKey(linkedClassName) && toPersist.getUpdatedObjects().get(linkedClassName).get(loId) != null) { INakedObject newObj = linkedClass.newInstance(); int i = 0; for (Object id : loId.getFieldValues()) { setIdField(loIds, loId, newObj, i, id); i++; } setObject(o, pd, newObj); } } } } return true; } private void setObject(INakedObject o, PropertyDescriptor pd, INakedObject newObj) throws IllegalAccessException, InvocationTargetException { Object[] args = new Object[1]; args[0] = newObj; pd.getWriteMethod().invoke(o, args); } private void setIdField(Set<PropertyDescriptor> loIds, com.hiperf.common.ui.shared.util.Id loId, INakedObject newObj, int i, Object id) throws IllegalAccessException, InvocationTargetException { for (PropertyDescriptor pdId : loIds) { if (pdId.getName().equals(loId.getFieldNames().get(i))) { Object[] aa = new Object[1]; aa[0] = id; pdId.getWriteMethod().invoke(newObj, aa); break; } } } public com.hiperf.common.ui.shared.util.Id getId(INakedObject o) throws IllegalAccessException, InvocationTargetException { return getId(o, idsByClassName.get(o.getClass().getName())); } private com.hiperf.common.ui.shared.util.Id getId(INakedObject o, Set<PropertyDescriptor> ids) throws IllegalAccessException, InvocationTargetException { com.hiperf.common.ui.shared.util.Id myOldId; List<Object> idList = new ArrayList<Object>(); List<String> idFields = new ArrayList<String>(); for (PropertyDescriptor pd : ids) { idFields.add(pd.getName()); idList.add(pd.getReadMethod().invoke(o, StorageService.emptyArg)); } myOldId = new com.hiperf.common.ui.shared.util.Id(idFields, idList); return myOldId; } public com.hiperf.common.ui.shared.util.Id getId(String s, String className) { if (s != null && s.length() > 0) { String[] ss = s.split(","); int l = ss.length; PropertyDescriptor[] pds = propertyDescriptorsByClassName.get(className); List<String> fieldNames = new ArrayList<String>(l); List<Object> fieldValues = new ArrayList<Object>(l); int j = 0; for (int i = 0; i < l; i++) { String[] ids = ss[i].split(":"); String att = null; if (ids.length == 2) { j = 1; att = ids[0]; fieldNames.add(att); } else if (l == 1) { j = 0; att = idsByClassName.get(className).iterator().next().getName(); fieldNames.add(att); } if (att != null) { for (PropertyDescriptor pd : pds) { if (pd.getName().equals(att)) { if (pd.getPropertyType().equals(Long.class) || pd.getPropertyType().equals(long.class)) { fieldValues.add(Long.valueOf(ids[j])); } else if (pd.getPropertyType().equals(Integer.class) || pd.getPropertyType().equals(int.class)) { fieldValues.add(Long.valueOf(ids[j])); } else fieldValues.add(ids[j].toString()); } } } } return new com.hiperf.common.ui.shared.util.Id(fieldNames, fieldValues); } return null; } @Override public List<INakedObject> reload(String nakedObjectName, List<String> idFields, List<List<Object>> idList) throws PersistenceException { TransactionContext tc = null; List<INakedObject> l = new ArrayList<INakedObject>(idList.size()); try { Class<?> c = Class.forName(nakedObjectName); tc = createTransactionalContext(); EntityManager em = tc.getEm(); ITransaction tx = tc.getTx(); tx.begin(); if (idFields.size() == 1) { for (List myId : idList) { l.add((INakedObject) em.find(c, myId.get(0))); } l = deproxyEntities(nakedObjectName, l, true, null); } else { for (List myId : idList) { l.add((INakedObject) em.find(c, getCompositeId(c, idFields, myId))); } l = deproxyEntities(nakedObjectName, l, true, null); } return l; } catch (Exception e) { logger.log(Level.SEVERE, "Exception in reload : " + e.getMessage(), e); throw new PersistenceException("Exception in reload : " + e.getMessage(), e); } finally { finalizeTx(tc); } } private void finalizeTx(TransactionContext tc) { if (tc != null) { try { tc.rollback(); } catch (TransactionException e) { logger.log(Level.SEVERE, "Exception in rollback...", e); } close(tc); } } @Override public INakedObject getLinkedObject(String nakedObjectName, com.hiperf.common.ui.shared.util.Id id, String attributeName) throws PersistenceException { INakedObject o = null; EntityManager em = null; try { em = getEntityManager(); if (id.getFieldNames().size() == 1) { o = (INakedObject) em.find(Class.forName(nakedObjectName), id.getFieldValues().get(0)); } else { Class c = Class.forName(nakedObjectName); o = (INakedObject) em.find(c, getCompositeId(c, id.getFieldNames(), id.getFieldValues())); } if (o != null) { return deproxyLinkedObject(o, attributeName, em); } return null; } catch (Exception e) { logger.log(Level.SEVERE, "Exception in getLinkedObject " + e.getMessage(), e); throw new PersistenceException("Exception in getLinkedObject " + e.getMessage(), e); } finally { closeEntityManager(em); } } @Override public NakedObjectsList getCollectionInverse(String wrappedClassName, String attribute, com.hiperf.common.ui.shared.util.Id id, int page, int nbRows, ObjectsToPersist toPersist, String sortAttribute, Boolean asc) throws PersistenceException { INakedObject o = null; EntityManager em = null; TransactionContext tc = null; Map<com.hiperf.common.ui.shared.util.Id, INakedObject> res = new HashMap<com.hiperf.common.ui.shared.util.Id, INakedObject>(); try { Map<Object, IdHolder> newIdByOldId = new HashMap<Object, IdHolder>(); tc = createTransactionalContext(); em = tc.getEm(); ITransaction tx = tc.getTx(); tx.begin(); doPersist(toPersist, null, res, newIdByOldId, em, true, null); String jpql = "select size(o." + attribute + ") from " + wrappedClassName + " o"; String currentFilter = getIdClause(id); jpql += " where " + currentFilter; Query q = em.createQuery(jpql); Integer count = getSize(id, newIdByOldId, q); int lastTotal = nbRows * (page - 1); if (count > 0 && count > lastTotal) { jpql = "select j from " + wrappedClassName + " o inner join o." + attribute + " j "; jpql += "where " + currentFilter; if (asc != null && sortAttribute != null) { if (asc) { jpql += " order by j." + sortAttribute + " asc"; } else { jpql += " order by j." + sortAttribute + " desc"; } } q = em.createQuery(jpql); int i = 0; for (Object idObj : id.getFieldValues()) { if (id.isLocal() && newIdByOldId.containsKey(idObj)) q.setParameter("id" + i, newIdByOldId.get(idObj).getId()); else q.setParameter("id" + i, idObj); } q.setFirstResult(lastTotal); q.setMaxResults(nbRows); List<INakedObject> list = q.getResultList(); if (list != null && !list.isEmpty()) { String name = list.get(0).getClass().getName(); Map<String, Map<Object, Object>> oldIdByNewMap = buildInverseIdMap(newIdByOldId); list = deproxyEntities(name, list, true, oldIdByNewMap); } return new NakedObjectsList(list, count.intValue(), nbRows, currentFilter); } else return null; } catch (Exception e) { logger.log(Level.SEVERE, "Exception in getCollection " + e.getMessage(), e); throw new PersistenceException("Exception in getCollection " + e.getMessage(), e); } finally { finalizeTx(tc); } } public Map<String, Map<Object, Object>> buildInverseIdMap(Map<Object, IdHolder> newIdByOldId) { Map<String, Map<Object, Object>> oldIdByNewMap = null; if (!newIdByOldId.isEmpty()) { oldIdByNewMap = new HashMap<String, Map<Object, Object>>(); for (Entry<Object, IdHolder> e : newIdByOldId.entrySet()) { IdHolder id = e.getValue(); Map<Object, Object> map = oldIdByNewMap.get(id.getClassName()); if (map == null) { map = new HashMap<Object, Object>(); oldIdByNewMap.put(id.getClassName(), map); } map.put(id.getId(), e.getKey()); } } return oldIdByNewMap; } @Override public NakedObjectsList getCollection(String className, com.hiperf.common.ui.shared.util.Id id, String attributeName, int page, int nbRows, ObjectsToPersist toPersist) throws PersistenceException { return getSortedCollection(className, id, attributeName, null, null, page, nbRows, toPersist); } @Override public NakedObjectsList getSortedCollection(String nakedObjectName, com.hiperf.common.ui.shared.util.Id id, String attributeName, String sortAttribute, Boolean asc, int page, int rowsPerPage, ObjectsToPersist toPersist) throws PersistenceException { EntityManager em = null; TransactionContext tc = null; Map<com.hiperf.common.ui.shared.util.Id, INakedObject> res = new HashMap<com.hiperf.common.ui.shared.util.Id, INakedObject>(); try { Map<Object, IdHolder> newIdByOldId = new HashMap<Object, IdHolder>(); tc = createTransactionalContext(); em = tc.getEm(); ITransaction tx = tc.getTx(); tx.begin(); doPersist(toPersist, null, res, newIdByOldId, em, true, null); String jpql = "select count(*) from " + nakedObjectName + " o"; String currentFilter = getIdClause(id, attributeName); jpql += " where " + currentFilter; Query q = em.createQuery(jpql); Long count = getCount(id, newIdByOldId, q); int lastTotal = rowsPerPage * (page - 1); if (count > 0 && count > lastTotal) { jpql = "select o from " + nakedObjectName + " o "; jpql += "where " + currentFilter; if (asc != null) { if (asc) { jpql += " order by o." + sortAttribute + " asc"; } else { jpql += " order by o." + sortAttribute + " desc"; } } q = em.createQuery(jpql); int i = 0; for (Object idObj : id.getFieldValues()) { if (id.isLocal() && newIdByOldId.containsKey(idObj)) q.setParameter("id" + i, newIdByOldId.get(idObj).getId()); else q.setParameter("id" + i, idObj); } q.setFirstResult(lastTotal); q.setMaxResults(rowsPerPage); List<INakedObject> list = q.getResultList(); if (list != null && !list.isEmpty()) { String name = list.get(0).getClass().getName(); Map<String, Map<Object, Object>> oldIdByNewIdMap = buildInverseIdMap(newIdByOldId); list = deproxyEntities(name, list, true, oldIdByNewIdMap); } NakedObjectsList l = new NakedObjectsList(list, count.intValue(), rowsPerPage, currentFilter); l.setConstantFilterFields(new String[] { attributeName }); return l; } else return null; } catch (Exception e) { logger.log(Level.SEVERE, "Exception in getCollection " + e.getMessage(), e); throw new PersistenceException("Exception in getCollection " + e.getMessage(), e); } finally { finalizeTx(tc); } } private Integer getSize(com.hiperf.common.ui.shared.util.Id id, Query q) { int i = 0; for (Object idObj : id.getFieldValues()) { q.setParameter("id" + i, idObj); } return (Integer) q.getResultList().get(0); } private Long getCount(com.hiperf.common.ui.shared.util.Id id, Map<Object, IdHolder> newIdByOldId, Query q) { int i = 0; for (Object idObj : id.getFieldValues()) { if (id.isLocal() && newIdByOldId.containsKey(idObj)) q.setParameter("id" + i, newIdByOldId.get(idObj).getId()); else q.setParameter("id" + i, idObj); } Long count = (Long) q.getResultList().get(0); return count; } private Integer getSize(com.hiperf.common.ui.shared.util.Id id, Map<Object, IdHolder> newIdByOldId, Query q) { int i = 0; for (Object idObj : id.getFieldValues()) { if (id.isLocal() && newIdByOldId.containsKey(idObj)) q.setParameter("id" + i, newIdByOldId.get(idObj).getId()); else q.setParameter("id" + i, idObj); } Integer count = (Integer) q.getResultList().get(0); return count; } private String getIdClause(com.hiperf.common.ui.shared.util.Id id) { String currentFilter = ""; int i = 0; for (String name : id.getFieldNames()) { currentFilter += "o." + name + " = :id" + i; if (i < id.getFieldNames().size() - 1) currentFilter += " and "; } return currentFilter; } private String getIdClause(com.hiperf.common.ui.shared.util.Id id, String attributeName) { String currentFilter = ""; int i = 0; for (String name : id.getFieldNames()) { currentFilter += "o." + attributeName + "." + name + " = :id" + i; if (i < id.getFieldNames().size() - 1) currentFilter += " and "; } return currentFilter; } public void removeFilter(Long id) throws PersistenceException { TransactionContext tc = null; try { tc = createTransactionalContext(); EntityManager em = tc.getEm(); ITransaction tx = tc.getTx(); Filter f = em.find(Filter.class, id); List<FilterValue> values = f.getValues(); if (values != null && !values.isEmpty()) { for (FilterValue fv : values) { em.remove(fv); } } values.clear(); em.remove(f); tx.begin(); tx.commit(); } catch (Exception e) { catchPersistException(tc, e); throw new PersistenceException(e.getMessage(), e); } finally { if (tc != null) close(tc); } } private void catchPersistException(TransactionContext tc, Exception e) { logger.log(Level.SEVERE, "Exception in persist : " + e.getMessage(), e); try { if (tc != null) tc.rollback(); } catch (Exception ee) { } } @Override public Long saveFilter(Filter f, String userName) throws PersistenceException { TransactionContext tc = null; try { tc = createTransactionalContext(); EntityManager em = tc.getEm(); ITransaction tx = tc.getTx(); tx.begin(); Long id = null; Filter orig = null; if (f.getId() != null) orig = em.find(Filter.class, f.getId()); if (orig != null) { if (orig.getValues() != null && !orig.getValues().isEmpty()) { for (FilterValue fv : orig.getValues()) { em.remove(fv); } orig.getValues().clear(); } orig.setName(f.getName()); orig.setClassName(f.getClassName()); orig.setViewName(f.getViewName()); orig.setUserName(userName); ArrayList<FilterValue> l = new ArrayList<FilterValue>(); orig.setValues(l); for (FilterValue fv : f.getValues()) { fv.setId(null); fv.setFilter(orig); em.persist(fv); l.add(fv); } if (f.getSortAttribute() != null) { orig.setSortAttribute(f.getSortAttribute()); orig.setSortAsc(f.getSortAsc()); } em.merge(orig); id = orig.getId(); } else { f.setId(null); f.setCreateUser(userName); f.setUserName(userName); for (FilterValue fv : f.getValues()) fv.setId(null); em.persist(f); id = f.getId(); } tx.commit(); return id; } catch (Exception e) { catchPersistException(tc, e); throw new PersistenceException(e.getMessage(), e); } finally { if (tc != null) close(tc); } } @Override public NakedObjectsList sort(String className, String currentFilter, String attribute, boolean distinct, boolean asc, int page, int nbRows, ObjectsToPersist toPersist, Locale locale) throws PersistenceException { String order = getSortClause(attribute); if (!asc) order += " DESC"; return queryData(className, currentFilter, page, nbRows, order, toPersist, locale, distinct); } public String getSortClause(String attribute) { List<String> joins = new ArrayList<String>(); String[] atts = attribute.split(","); String order = " order by "; int i = 0; for (String att : atts) { att = att.trim(); int j = att.indexOf("."); if (j > 0) { joins.add(att.substring(0, j)); order += "jjjs" + joins.size() + att.substring(j); } else { order += "o." + att; } if (i < atts.length - 1) order += ", "; i++; } if (!joins.isEmpty()) { StringBuilder sb = new StringBuilder(); int j = 1; for (String s : joins) { sb.append("left outer join o.").append(s).append(" jjjs").append(j).append(" "); j++; } order = sb.toString() + "@" + order; } return order; } @Override public void getExtractedData(HttpServletRequest req, HttpServletResponse resp, String className) throws ServletException { //col index / Attribute, label Map<Integer, Object[]> map = new HashMap<Integer, Object[]>(); logger.fine("Class = " + className); EntityManager em = null; try { ExcelHelper.fillObjectMap(req, className, map); em = getEntityManager(); StringBuilder jpqlSb = new StringBuilder("select distinct o from ").append(className); String filter = null; Object[] o = map.get(IConstants.KEY_FILTER); String jpql; List res = null; Query q = null; if (o != null) { if (o.length == 1) filter = (String) o[0]; jpql = appendWhereClause(filter, jpqlSb.toString()); List<Date> dtParams = new ArrayList<Date>(); jpql = replaceDateParameters(jpql, dtParams); q = em.createQuery(jpql); if (!dtParams.isEmpty()) { for (int i = 0; i < dtParams.size(); i++) { q.setParameter("dt" + i, dtParams.get(i)); } } } else { o = map.get(IConstants.KEY_LAZY); if (o != null && o.length == 1 && (Boolean) o[0]) { com.hiperf.common.ui.shared.util.Id id = (com.hiperf.common.ui.shared.util.Id) map .get(IConstants.KEY_ID)[0]; String mappedBy = null; o = map.get(IConstants.KEY_MAPPED_BY); if (o != null && o.length == 1) { mappedBy = (String) o[0]; } o = map.get(IConstants.KEY_ATTRIBUTE); String att = null; if (o != null && o.length == 1) { att = (String) o[0]; } if (mappedBy != null) { String currentFilter = getIdClause(id, mappedBy); jpql = "select o from " + className + " o where " + currentFilter; } else { String currentFilter = getIdClause(id); jpql = "select j from " + className + " o inner join o." + att + " j where " + currentFilter; } q = em.createQuery(jpql); int i = 0; for (Object idObj : id.getFieldValues()) { q.setParameter("id" + i, idObj); i++; } } else { q = em.createQuery(jpqlSb.append(" o").toString()); } } if (q != null) { setQueryTimeout(q); res = q.getResultList(); } ExcelHelper.sendResponse(resp, className, map, res); } catch (Exception e) { logger.log(Level.SEVERE, "Exception while querying data for export", e); throw new ServletException("Exception while querying data for export", e); } finally { closeEntityManager(em); } } @Override public void saveConfiguration(String viewName, String className, int nbRows, List<HeaderInfo> headers, ScreenLabels sl, String connectedUser, LanguageEnum language) throws PersistenceException { TransactionContext tc = null; try { tc = createTransactionalContext(); EntityManager em = tc.getEm(); ITransaction tx = tc.getTx(); tx.begin(); List<ScreenConfig> l = em.createQuery( "select o from ScreenConfig o where o.viewName = :vN and o.className = :clazz and o.createUser = :user") .setParameter("vN", viewName).setParameter("clazz", className) .setParameter("user", connectedUser).getResultList(); ScreenConfig sc = null; Map<String, ScreenHeaderInfo> headerByAttribute = new HashMap<String, ScreenHeaderInfo>(); if (l != null && !l.isEmpty()) { sc = l.get(0); if (l.size() > 1) { for (int i = 1; i < l.size(); i++) { em.remove(l.get(i)); } } for (ScreenHeaderInfo hi : sc.getHeaders()) { headerByAttribute.put(hi.getAttribute(), hi); } } else { sc = new ScreenConfig(); sc.setViewName(viewName); sc.setClassName(className); sc.setCreateUser(connectedUser); em.persist(sc); } sc.setNbRows(nbRows); if (sl != null) { boolean found = false; if (sc.getLabels() != null && !sc.getLabels().isEmpty()) { for (ScreenLabels lb : sc.getLabels()) { if (lb.getLanguage().equals(language)) { if (sl.getCreateLabel() != null) lb.setCreateLabel(sl.getCreateLabel()); if (sl.getEditLabel() != null) lb.setEditLabel(sl.getEditLabel()); if (sl.getFormLabel() != null) lb.setFormLabel(sl.getFormLabel()); if (sl.getSelectLabel() != null) lb.setSelectLabel(sl.getSelectLabel()); if (sl.getTableLabel() != null) lb.setTableLabel(sl.getTableLabel()); if (sl.getViewLabel() != null) lb.setViewLabel(sl.getViewLabel()); em.merge(lb); found = true; break; } } } if (!found) { sl.setScreenConfig(sc); em.persist(sl); } } for (HeaderInfo hi : headers) { ScreenHeaderInfo shi = headerByAttribute.get(hi.getAttribute()); if (shi == null) { shi = new ScreenHeaderInfo(); shi.setAttribute(hi.getAttribute()); shi.setDisplayed(hi.isDisplayed()); shi.setScreenConfig(sc); shi.setIndex(hi.getIndex()); em.persist(shi); } else { shi.setDisplayed(hi.isDisplayed()); shi.setScreenConfig(sc); shi.setIndex(hi.getIndex()); em.merge(shi); } if (hi.getLabel() != null) { boolean found = false; List<Label> labels = shi.getLabels(); if (labels != null && !labels.isEmpty()) { Iterator<Label> it = labels.iterator(); while (it.hasNext()) { Label lbl = it.next(); if (lbl.getLanguage().equals(language)) { if (hi.getLabel().length() > 0) { lbl.setLabel(hi.getLabel()); em.merge(lbl); } else { em.remove(lbl); it.remove(); } found = true; break; } } } if (!found) { Label lbl = new Label(); lbl.setLanguage(language); lbl.setLabel(hi.getLabel()); lbl.setHeader(shi); em.persist(lbl); } } } tx.commit(); } catch (Exception e) { catchPersistException(tc, e); throw new PersistenceException(e.getMessage(), e); } finally { if (tc != null) close(tc); } } @Override public Map<String, TableConfig> getScreenConfigurations(String connectedUser, LanguageEnum language) throws PersistenceException { EntityManager em = null; try { em = getEntityManager(); Map<String, TableConfig> map = new HashMap<String, TableConfig>(); List<ScreenConfig> l = em.createQuery("select o from ScreenConfig o where o.createUser = :user") .setParameter("user", connectedUser).getResultList(); Map<String, Map<com.hiperf.common.ui.shared.util.Id, INakedObject>> deproxyContext = new HashMap<String, Map<com.hiperf.common.ui.shared.util.Id, INakedObject>>(); if (l != null && !l.isEmpty()) { for (ScreenConfig sc : l) { addHeader(language, map, sc, em, deproxyContext); } } String hql = "select o from ScreenConfig o where o.defaultConfig = true"; Query q = em.createQuery(hql); l = q.getResultList(); if (l != null && !l.isEmpty()) { for (ScreenConfig sc : l) { String key = getViewKey(sc); if (!map.containsKey(key)) { addHeader(language, map, sc, em, deproxyContext); } } } return map; } catch (javax.persistence.PersistenceException pe) { Throwable cause = pe.getCause(); if (cause != null && cause instanceof SQLGrammarException) { logger.log(Level.SEVERE, "SQLGrammarException " + cause.getMessage(), cause); throw new PersistenceException("Exception in getScreenConfigurations " + cause.getMessage(), cause, true); } else { logger.log(Level.SEVERE, "Exception in getScreenConfigurations " + pe.getMessage(), pe); throw new PersistenceException("Exception in getScreenConfigurations " + pe.getMessage(), pe); } } catch (SQLGrammarException e) { logger.log(Level.SEVERE, "SQLGrammarException " + e.getMessage(), e); throw new PersistenceException("Exception in getScreenConfigurations " + e.getMessage(), e, true); } catch (Exception e) { logger.log(Level.SEVERE, "Exception in getScreenConfigurations " + e.getMessage(), e); throw new PersistenceException("Exception in getScreenConfigurations " + e.getMessage(), e); } finally { closeEntityManager(em); } } @Override public void addHeader(LanguageEnum language, Map<String, TableConfig> map, ScreenConfig sc, EntityManager em, Map<String, Map<com.hiperf.common.ui.shared.util.Id, INakedObject>> deproxyContext) throws PersistenceException { TableConfig tc = getTableConfig(language, sc, em, deproxyContext); String key = getViewKey(sc); map.put(key, tc); } @Override public TableConfig getTableConfig(LanguageEnum language, ScreenConfig sc, EntityManager em, Map<String, Map<com.hiperf.common.ui.shared.util.Id, INakedObject>> deproxyContext) throws PersistenceException { List<HeaderInfo> list = null; List<ScreenHeaderInfo> headers = sc.getHeaders(); if (headers != null && !headers.isEmpty()) { list = new ArrayList<HeaderInfo>(); Class cl = null; try { cl = Class.forName(sc.getClassName()); for (ScreenHeaderInfo shi : headers) { String att = shi.getAttribute(); try { cl.getDeclaredField(att); } catch (NoSuchFieldException e) { logger.info("Field " + att + " not found"); String name = att.substring(0, 1).toUpperCase() + att.substring(1); String meth = "get" + name; try { cl.getMethod(meth); } catch (NoSuchMethodException e1) { logger.info("Method " + meth + " not found"); meth = "is" + name; try { cl.getMethod(meth); } catch (NoSuchMethodException e2) { logger.log(Level.SEVERE, "Field " + att + " not Found !!!", e2); continue; } } } String label = null; List<Label> labels = shi.getLabels(); if (labels != null && !labels.isEmpty()) { for (Label lbl : labels) { if (lbl.getLanguage().equals(language)) { label = lbl.getLabel(); break; } } } list.add(new HeaderInfo(att, label, shi.getIndex(), shi.isDisplayed(), shi.getEditable())); } } catch (ClassNotFoundException | SecurityException e) { logger.log(Level.SEVERE, "Field not Found !!!", e); throw new PersistenceException(e.getMessage()); } } List<ScreenLabels> lbls = sc.getLabels(); ScreenLabels scLbls = null; if (lbls != null && !lbls.isEmpty()) { for (ScreenLabels lbl : lbls) { if (lbl.getLanguage().equals(language)) { scLbls = lbl; break; } } } scLbls = (ScreenLabels) deproxyNakedObject(scLbls, em, deproxyContext); return new TableConfig(sc.getNbRows(), scLbls, list); } @Override public String getViewKey(ScreenConfig sc) { return sc.getViewName() == null ? sc.getClassName() : sc.getViewName() + "#" + sc.getClassName(); } /*public TableConfig getScreenConfiguration(String className, String connectedUser) throws PersistenceException { EntityManager em= null; try { em = getEntityManager(); List<HeaderInfo> list = new ArrayList<HeaderInfo>(); List<ScreenConfig> l = em.createQuery("select o from ScreenConfig o where o.className = :clazz and o.userName = :user") .setParameter("clazz", className) .setParameter("user", connectedUser) .getResultList(); if(l!=null&&!l.isEmpty()) { ScreenConfig sc = l.get(0); return getTableConfig(get, sc); } return null; } catch (Exception e) { logger.log(Level.SEVERE, "Exception in getScreenConfigurations "+e.getMessage(), e); throw new PersistenceException("Exception in getScreenConfigurations "+e.getMessage(), e); } finally { closeEntityManager(em); } }*/ @Override public void downloadFile(HttpServletResponse resp, String fileClass, String fileNameField, String fileStorageField, String fileId) throws PersistenceException { String id = getIdFieldFromFileStorageClass(fileClass); EntityManager em = null; try { em = getEntityManager(); List<Object[]> l = em.createQuery("select o." + fileNameField + ", o." + fileStorageField + " from " + fileClass + " o where o." + id + " = " + fileId).getResultList(); if (l != null && !l.isEmpty()) { Object[] o = l.get(0); String name = (String) o[0]; byte[] b = (byte[]) o[1]; if (b != null && b.length > 0) { sendFile(resp, name, b); } } } catch (Exception e) { logger.log(Level.SEVERE, "Exception in downloadFile " + e.getMessage(), e); throw new PersistenceException("Exception in downloadFile " + e.getMessage(), e); } finally { closeEntityManager(em); } } @Override public void sendFile(HttpServletResponse resp, String name, byte[] b) throws IOException, ServletException { IOUtils.sendAttachment(resp, b, name); } private String getIdFieldFromFileStorageClass(String fileClass) throws PersistenceException { Set<PropertyDescriptor> ids = idsByClassName.get(fileClass); if (ids == null) { String msg = "Exception in downloadFile : class " + fileClass + " is not a persistent entity"; logger.log(Level.SEVERE, msg); throw new PersistenceException(msg); } if (ids.size() != 1) throw new PersistenceException("File storage class " + fileClass + " must have one field as Id"); String id = ids.iterator().next().getName(); return id; } @Override public Object saveFile(String fileClass, String fileNameField, String fileStorageField, String fileName, FileItem item) throws PersistenceException { getIdFieldFromFileStorageClass(fileClass); TransactionContext tc = null; try { tc = createTransactionalContext(); EntityManager em = tc.getEm(); ITransaction tx = tc.getTx(); tx.begin(); Class clazz = Class.forName(fileClass); Object o = clazz.newInstance(); for (PropertyDescriptor pd : propertyDescriptorsByClassName.get(fileClass)) { if (fileNameField.equals(pd.getName())) { pd.getWriteMethod().invoke(o, fileName); } else if (fileStorageField.equals(pd.getName())) { pd.getWriteMethod().invoke(o, item.get()); } } em.persist(o); tx.commit(); return idsByClassName.get(fileClass).iterator().next().getReadMethod().invoke(o, new Object[0]); } catch (Exception e) { logger.log(Level.SEVERE, "Exception in saveFile : " + e.getMessage(), e); try { if (tc != null) tc.rollback(); } catch (Exception ee) { } throw new PersistenceException(e.getMessage(), e); } finally { if (tc != null) close(tc); } } @Override public String replaceFile(String fileClass, String fileNameField, String fileStorageField, String fileName, FileItem fileItem, String existingId) throws PersistenceException { String idField = getIdFieldFromFileStorageClass(fileClass); boolean error = false; TransactionContext tc = null; Object id = null; PropertyDescriptor[] pds = propertyDescriptorsByClassName.get(fileClass); try { id = getFileId(existingId, idField, pds); tc = createTransactionalContext(); EntityManager em = tc.getEm(); ITransaction tx = tc.getTx(); tx.begin(); Object o; Class<?> clazz = Class.forName(fileClass); o = em.find(clazz, id); for (PropertyDescriptor pd : pds) { if (fileNameField.equals(pd.getName())) { pd.getWriteMethod().invoke(o, fileName); } else if (fileStorageField.equals(pd.getName())) { pd.getWriteMethod().invoke(o, fileItem.get()); } } em.merge(o); tx.commit(); //idsByClassName.get(fileClass).iterator().next().getReadMethod().invoke(o, new Object[0]); } catch (Exception e) { error = true; logger.log(Level.SEVERE, "Exception in saveFile : " + e.getMessage(), e); try { if (tc != null) tc.rollback(); } catch (Exception ee) { } } finally { if (tc != null) { if (!error) close(tc); else tc.close(); } } if (error) { try { tc = createTransactionalContext(); EntityManager em = tc.getEm(); ITransaction tx = tc.getTx(); tx.begin(); Class<?> clazz = Class.forName(fileClass); em.createQuery("delete from " + fileClass + " o where o." + idField + " = :id") .setParameter("id", id).executeUpdate(); Object newDoc = clazz.newInstance(); for (PropertyDescriptor pd : pds) { if (fileNameField.equals(pd.getName())) { pd.getWriteMethod().invoke(newDoc, fileName); } else if (fileStorageField.equals(pd.getName())) { pd.getWriteMethod().invoke(newDoc, fileItem.get()); } } em.persist(newDoc); tx.commit(); for (PropertyDescriptor pd : pds) { if (idField.equals(pd.getName())) { existingId = pd.getReadMethod().invoke(newDoc, new String[0]).toString(); break; } } } catch (Exception e) { logger.log(Level.SEVERE, "Exception in saveFile : " + e.getMessage(), e); try { if (tc != null) tc.rollback(); } catch (Exception ee) { } throw new PersistenceException(e.getMessage(), e); } finally { if (tc != null) close(tc); } } return existingId; } @Override public Object getFileId(String existingId, String fileClass) throws PersistenceException { String idField = getIdFieldFromFileStorageClass(fileClass); try { return getFileId(existingId, idField, propertyDescriptorsByClassName.get(fileClass)); } catch (IllegalAccessException e) { throw new PersistenceException(e); } catch (InvocationTargetException e) { throw new PersistenceException(e); } catch (NoSuchMethodException e) { throw new PersistenceException(e); } } @Override public Object getFileId(String existingId, String idField, PropertyDescriptor[] pds) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException, PersistenceException { Object id = null; for (PropertyDescriptor pd : pds) { if (pd.getName().equals(idField)) { Class<?> propertyType = pd.getPropertyType(); if (Number.class.isAssignableFrom(propertyType)) id = propertyType.getMethod("valueOf", String.class).invoke(propertyType, existingId); else if (propertyType.equals(String.class)) id = existingId; else throw new PersistenceException("Type " + propertyType + " not supported"); } } return id; } @Override public String checkExists(String className, String attribute, String value, Locale locale) throws PersistenceException { EntityManager em = null; try { em = getEntityManager(); boolean isString; if (value != null) { PropertyDescriptor[] pds = (PropertyDescriptor[]) propertyDescriptorsByClassName.get(className); boolean isNumber = false; isString = false; for (PropertyDescriptor pd : pds) { if (pd.getName().equals(attribute)) { Class propertyType = pd.getPropertyType(); if ((propertyType.isPrimitive()) || (Number.class.isAssignableFrom(propertyType))) { isNumber = true; break; } if (!(String.class.isAssignableFrom(propertyType))) break; isString = true; break; } } StringBuilder q = getCheckExistsQuery(className, attribute, value, isNumber, isString); Query q1 = em.createQuery(q.toString()); if (isString) q1.setParameter(1, value.toLowerCase()); List l = q1.getResultList(); ResourceBundle ressource; if ((l != null) && (l.size() > 0)) { return getUniqueErrorMsg(attribute, value, locale); } return null; } List l = em.createQuery("select 1 from " + className + " o where o." + attribute + " is null") .getResultList(); ResourceBundle ressource; if ((l != null) && (l.size() > 0)) { return getUniqueErrorMsg(attribute, value, locale); } return null; } catch (Exception e) { logger.log(Level.SEVERE, "Exception in checkExists " + e.getMessage(), e); throw new PersistenceException("Exception in checkExists " + e.getMessage(), e); } finally { closeEntityManager(em); } } public String getMessage(String key, Locale l) { ResourceBundle ressource = ResourceBundle.getBundle(SERVER_MESSAGES, l, PersistenceHelper.class.getClassLoader(), new UTF8Control()); return ressource.getString(key); } private String getUniqueErrorMsg(String attribute, String value, Locale locale) { ResourceBundle ressource = ResourceBundle.getBundle(SERVER_MESSAGES, locale, PersistenceHelper.class.getClassLoader(), new UTF8Control()); String lbl = null; try { lbl = ressource.getString(attribute); } catch (Exception e) { } if (lbl == null) lbl = attribute; return MessageFormat.format(ressource.getString("uniqueConstraintViolated").replaceAll("'", "''"), new Object[] { value, lbl }); } private StringBuilder getCheckExistsQuery(String className, String attribute, String value, boolean isNumber, boolean isString) { StringBuilder q = new StringBuilder("select 1 from " + className + " o where "); if (isString) { q.append("lower(o.").append(attribute).append(") = ?1"); } else if (isNumber) q.append("o.").append(attribute).append(" = ").append(value); else q.append("o.").append(attribute).append(" = '").append(StringUtils.replace(value, "'", "''")) .append("'"); return q; } @Override public String checkExists(String className, com.hiperf.common.ui.shared.util.Id id, String attribute, String value, Locale locale) throws PersistenceException { EntityManager em = null; try { Set<PropertyDescriptor> ids = idsByClassName.get(className); PropertyDescriptor[] idsArr = (PropertyDescriptor[]) ids.toArray(new PropertyDescriptor[0]); em = getEntityManager(); int i; if (value != null) { boolean isNumber = false; boolean isString = false; PropertyDescriptor[] pds = (PropertyDescriptor[]) propertyDescriptorsByClassName.get(className); Class<?> propertyType; for (PropertyDescriptor pd : pds) { if (pd.getName().equals(attribute)) { propertyType = pd.getPropertyType(); if ((propertyType.isPrimitive()) || (Number.class.isAssignableFrom(propertyType))) { isNumber = true; break; } if (!(String.class.isAssignableFrom(propertyType))) break; isString = true; break; } } StringBuilder q = getCheckExistsQuery(className, attribute, value, isNumber, isString); q.append(" and o."); i = 0; for (String att : id.getFieldNames()) { q.append(att); q.append(" != "); if (StorageService.isNumber(att, idsArr)) { q.append(id.getFieldValues().get(i)); } else { q.append(" '").append(StringUtils.replace(id.getFieldValues().get(i).toString(), "'", "''")) .append("'"); } ++i; if (i < id.getFieldNames().size()) q.append(" and o."); } Query q1 = em.createQuery(q.toString()); if (isString) q1.setParameter(1, value.toLowerCase()); List l = q1.getResultList(); if ((l != null) && (l.size() > 0)) { return getUniqueErrorMsg(attribute, value, locale); } return null; } StringBuilder q = new StringBuilder( "select 1 from " + className + " o where o." + attribute + " is null and o."); i = 0; for (String att : id.getFieldNames()) { q.append(att); q.append(" != "); if (StorageService.isNumber(att, idsArr)) { q.append(id.getFieldValues().get(i)); } else { q.append(" '"); q.append(StringUtils.replace(id.getFieldValues().get(i).toString(), "'", "''")); q.append("'"); } ++i; if (i < id.getFieldNames().size()) q.append(" and o."); } List l = em.createQuery(q.toString()).getResultList(); if ((l != null) && (l.size() > 0)) { return getUniqueErrorMsg(attribute, value, locale); } return null; } catch (Exception e) { logger.log(Level.SEVERE, "Exception in checkExists " + e.getMessage(), e); throw new PersistenceException("Exception in checkExists " + e.getMessage(), e); } finally { closeEntityManager(em); } } @Override public CollectionInfo getLazyCollection(String className, com.hiperf.common.ui.shared.util.Id id, String attribute) throws PersistenceException { EntityManager em = null; try { em = getEntityManager(); return getCollectionInfo(em, id, className, attribute); } catch (Exception e) { logger.log(Level.SEVERE, "Exception in getLazyCollection " + e.getMessage(), e); throw new PersistenceException("Exception in getLazyCollection " + e.getMessage(), e); } finally { closeEntityManager(em); } } public Collection<INakedObject> getByAttribute(String className, String att, Object value, EntityManager em) { return em.createQuery("select o from " + className + " o where o." + att + " = :val") .setParameter("val", value).getResultList(); } @Override public boolean hasManyToOne(String className) { Set<PropertyDescriptor> set = eagerObjectsByClassName.get(className); if (set == null || set.isEmpty()) { set = lazysByClassName.get(className); return set != null && !set.isEmpty(); } return true; } @Override public void shutdown() { try { emf.close(); instance = null; emf = null; emByThread = null; } catch (Exception e) { logger.log(Level.WARNING, "Exception in shutdown", e); } } @Override public void close(TransactionContext tc) { emByThread.remove(); tc.close(); } @Override public void close(EntityManager em) { emByThread.remove(); em.close(); } }