Search in sources :

Example 1 with DomainDAO

use of org.jaffa.beans.moulding.data.domain.DomainDAO in project jaffa-framework by jaffa-projects.

the class BeanMoulder method updateBeanData.

private static void updateBeanData(String path, DomainDAO source, UOW uow, MouldHandler handler, GraphMapping mapping, IPersistent domainObject) throws InstantiationException, IllegalAccessException, InvocationTargetException, ApplicationExceptions, FrameworkException {
    try {
        // Fire 'startBean' handler
        if (handler != null)
            handler.startBean(path, source, domainObject);
        // Reflect all normal fields
        for (Iterator it = mapping.getFields().iterator(); it.hasNext(); ) {
            String field = (String) it.next();
            if (source.hasChanged(field)) {
                Object value = getProperty(mapping.getDataFieldDescriptor(field), source);
                // if(value!=null)
                updateProperty(mapping.getDomainFieldDescriptor(field), value, domainObject);
            }
        }
        // Reflect any foreign keys
        for (Iterator it = mapping.getForeignFields().iterator(); it.hasNext(); ) {
            String field = (String) it.next();
            if (source.hasChanged(field)) {
                Object value = getProperty(mapping.getDataFieldDescriptor(field), source);
                if (value != null) {
                    // need to map foreign keys back
                    List targetKeys = mapping.getForeignKeys(field);
                    GraphMapping fMapping = MappingFactory.getInstance(mapping.getDataFieldDescriptor(field).getPropertyType());
                    Set sourceKeys = fMapping.getKeyFields();
                    int i = 0;
                    for (Iterator i2 = sourceKeys.iterator(); i2.hasNext(); i++) {
                        String sourceFld = (String) i2.next();
                        String targetFld = (String) targetKeys.get(i);
                        log.debug("Copy Foreign Key Field from " + sourceFld + " to " + targetFld);
                        Object value2 = getProperty(fMapping.getDataFieldDescriptor(sourceFld), value);
                        updateProperty(mapping.getRealDomainFieldDescriptor(targetFld), value2, domainObject);
                    }
                }
            }
        }
        // Store Record
        if (domainObject.isDatabaseOccurence()) {
            log.debug("UOW.Update Domain Object");
            // Fire 'startBeanUpdate' handler
            if (handler != null)
                handler.startBeanUpdate(path, source, domainObject);
            uow.update(domainObject);
            // Fire 'endBeanUpdate' handler
            if (handler != null)
                handler.endBeanUpdate(path, source, domainObject);
        } else {
            log.debug("UOW.Add Domain Object");
            // Fire 'startBeanAdd' handler
            if (handler != null)
                handler.startBeanAdd(path, source, domainObject);
            uow.add(domainObject);
            // Fire 'endBeanAdd' handler
            if (handler != null)
                handler.endBeanAdd(path, source, domainObject);
        }
        // Reflect any related objects
        for (Iterator it = mapping.getRelatedFields().iterator(); it.hasNext(); ) {
            String field = (String) it.next();
            if (source.hasChanged(field)) {
                // Only do the update if the source object was updated!
                Object value = getProperty(mapping.getDataFieldDescriptor(field), source);
                if (value != null) {
                    if (value.getClass().isArray()) {
                        // The related field is an array of objects (one-to-many)
                        Object[] values = (Object[]) value;
                        for (int i = 0; i < values.length; i++) {
                            // Assumes its a DAO....what else could it be?
                            DomainDAO dao = (DomainDAO) values[i];
                            if (dao != null) {
                                updateChildBean(path + "." + field + "[" + i + "]", dao, uow, handler, domainObject, mapping, field);
                            }
                        }
                    } else {
                        // Or a single Object (one-to-one)
                        // Assumes its a DAO....what else could it be?
                        DomainDAO dao = (DomainDAO) value;
                        updateChildBean(path + "." + field, dao, uow, handler, domainObject, mapping, field);
                    }
                }
            }
        }
        // Fire 'endBean' handler
        if (handler != null)
            handler.endBean(path, source, domainObject);
    } catch (ApplicationException e) {
        ApplicationExceptions aes = new ApplicationExceptions();
        aes.add(e);
        throw aes;
    }
}
Also used : Set(java.util.Set) ApplicationException(org.jaffa.exceptions.ApplicationException) ApplicationExceptions(org.jaffa.exceptions.ApplicationExceptions) Iterator(java.util.Iterator) DomainDAO(org.jaffa.beans.moulding.data.domain.DomainDAO) ArrayList(java.util.ArrayList) List(java.util.List) GraphMapping(org.jaffa.beans.moulding.mapping.GraphMapping)

Example 2 with DomainDAO

use of org.jaffa.beans.moulding.data.domain.DomainDAO in project jaffa-framework by jaffa-projects.

the class BeanMoulder method printBean.

/**
 * Same as printBean(Object source), except the objectStack lists all the parent
 * objects its printed, and if this is one of them, it stops. This allows detection
 * of possible infinite recusion.
 * @param source Javabean who's contents should be printed
 * @param objectStack List of objects already traversed
 * @return multi-line string of this beans properties and their values
 */
public static String printBean(Object source, List objectStack) {
    if (source == null)
        return null;
    // Prevent infinite object recursion
    if (objectStack != null)
        if (objectStack.contains(source))
            return "Object Already Used. " + source.getClass().getName() + "@" + source.hashCode();
        else
            objectStack.add(source);
    else {
        objectStack = new ArrayList();
        objectStack.add(source);
    }
    StringBuffer out = new StringBuffer();
    out.append(source.getClass().getName());
    out.append("\n");
    try {
        BeanInfo sInfo = Introspector.getBeanInfo(source.getClass());
        PropertyDescriptor[] sDescriptors = sInfo.getPropertyDescriptors();
        if (sDescriptors != null && sDescriptors.length != 0)
            for (int i = 0; i < sDescriptors.length; i++) {
                PropertyDescriptor sDesc = sDescriptors[i];
                Method sm = sDesc.getReadMethod();
                if (sm != null && sDesc.getWriteMethod() != null) {
                    if (!sm.isAccessible())
                        sm.setAccessible(true);
                    Object sValue = sm.invoke(source, (Object[]) null);
                    out.append("  ");
                    out.append(sDesc.getName());
                    if (source instanceof DomainDAO) {
                        if (((DomainDAO) source).hasChanged(sDesc.getName()))
                            out.append("*");
                    }
                    out.append("=");
                    if (sValue == null)
                        out.append("<--NULL-->\n");
                    else if (sm.getReturnType().isArray()) {
                        StringBuffer out2 = new StringBuffer();
                        out2.append("Array of ");
                        out2.append(sm.getReturnType().getComponentType().getName());
                        out2.append("\n");
                        // Loop through array
                        Object[] a = (Object[]) sValue;
                        for (int j = 0; j < a.length; j++) {
                            out2.append("[");
                            out2.append(j);
                            out2.append("] ");
                            if (a[j] == null)
                                out2.append("<--NULL-->");
                            else if (DomainDAO.class.isAssignableFrom(a[j].getClass()))
                                out2.append(((DomainDAO) a[j]).toString(objectStack));
                            else
                                // out2.append(StringHelper.linePad(a[j].toString(), 4, " ",true));
                                out2.append(a[j].toString());
                        }
                        out.append(StringHelper.linePad(out2.toString(), 4, " ", true));
                    } else {
                        if (DomainDAO.class.isAssignableFrom(sValue.getClass()))
                            out.append(StringHelper.linePad(((DomainDAO) sValue).toString(objectStack), 4, " ", true));
                        else {
                            out.append(StringHelper.linePad(sValue.toString(), 4, " ", true));
                            out.append("\n");
                        }
                    }
                }
            }
    } catch (IllegalAccessException e) {
        MouldException me = new MouldException(MouldException.ACCESS_ERROR, "???", e.getMessage());
        log.error(me.getLocalizedMessage(), e);
    // throw me;
    } catch (InvocationTargetException e) {
        MouldException me = new MouldException(MouldException.INVOCATION_ERROR, "???", e);
        log.error(me.getLocalizedMessage(), me.getCause());
    // throw me;
    } catch (IntrospectionException e) {
        MouldException me = new MouldException(MouldException.INTROSPECT_ERROR, "???", e.getMessage());
        log.error(me.getLocalizedMessage(), e);
    // throw me;
    }
    return out.toString();
}
Also used : PropertyDescriptor(java.beans.PropertyDescriptor) BeanInfo(java.beans.BeanInfo) ArrayList(java.util.ArrayList) IntrospectionException(java.beans.IntrospectionException) Method(java.lang.reflect.Method) InvocationTargetException(java.lang.reflect.InvocationTargetException) DomainDAO(org.jaffa.beans.moulding.data.domain.DomainDAO)

Example 3 with DomainDAO

use of org.jaffa.beans.moulding.data.domain.DomainDAO in project jaffa-framework by jaffa-projects.

the class BeanMoulder method moldFromDomain.

/**
 * Mould data from domain object and its related objects into a new JavaBean based
 * domain object graph, based on the defined mapping rules.
 * @param source Source object to mould data from, typically extends Persistent
 * @param target Target object to mould data to, typically extends DomainDAO
 * @param graph The mapping class with the rules of how to map this source object
 * @param filter Filter object that it is used to control what fields are populated or the target objects
 * @param objectPath  The path of this object being processed. This identifies possible parent
 * and/or indexed entries where this object is contained.
 * @param includeKeys true if key fields should be included in results regardless of the filters
 * @throws ApplicationExceptions Thrown if one or more application logic errors are generated during moulding
 * @throws FrameworkException Thrown if any runtime moulding error has occured.
 */
public static void moldFromDomain(Object source, Object target, GraphMapping graph, MappingFilter filter, String objectPath, boolean includeKeys) throws ApplicationExceptions, FrameworkException {
    if (graph == null)
        graph = MappingFactory.getInstance(target);
    // throw new InstantiationException("A GraphMapping must be supplied");
    if (filter == null)
        filter = new MappingFilter(graph);
    try {
        // get list of target fileds to populate
        String[] tFields = graph.getDataFieldNames();
        if (tFields != null && tFields.length != 0)
            for (int i = 0; i < tFields.length; i++) {
                // Try to map a source to a target
                String tName = tFields[i];
                String fullName = tName;
                if (objectPath != null)
                    fullName = objectPath + "." + fullName;
                if (filter == null || filter.isFieldIncluded(fullName) || (includeKeys && graph.isKeyField(tName))) {
                    String sName = graph.getDomainFieldName(tName);
                    PropertyDescriptor tDesc = graph.getDataFieldDescriptor(tName);
                    PropertyDescriptor sDesc = graph.getDomainFieldDescriptor(tName);
                    // DAO descriptor with a setter, and a DO descriptor with a getter
                    if (sDesc == null)
                        log.error("No Getter for " + tName + " in path " + fullName);
                    // incase getter is not public, make it available
                    Method sm = sDesc.getReadMethod();
                    if (!sm.isAccessible())
                        sm.setAccessible(true);
                    // get the setter, and make is available if needed
                    Method tm = tDesc.getWriteMethod();
                    if (!tm.isAccessible())
                        tm.setAccessible(true);
                    // Set the value if the source and target are the same datatype
                    Class tClass = tDesc.getPropertyType();
                    Class sClass = sDesc.getPropertyType();
                    if (tClass.isAssignableFrom(sClass)) {
                        // Get the value being copied
                        Object sValue = sm.invoke(source, (Object[]) null);
                        if (sValue != null) {
                            tm.invoke(target, new Object[] { sValue });
                            log.debug("Set " + tName + " = " + sValue);
                        } else
                            log.debug(tName + " no set, NULL value");
                    // See if there is a datatype mapper for these classes
                    } else if (DataTypeMapper.instance().isMappable(sClass, tClass)) {
                        // Get the value being copied
                        Object sValue = sm.invoke(source, (Object[]) null);
                        if (sValue != null) {
                            sValue = DataTypeMapper.instance().map(sValue, tClass);
                            tm.invoke(target, new Object[] { sValue });
                            log.debug("Set " + tName + " = " + sValue);
                        } else
                            log.debug(tName + " no set, NULL value");
                    // See if target is a DAO, this could be a foreign object or one-to-one relationship...
                    } else if (DomainDAO.class.isAssignableFrom(tClass) && IPersistent.class.isAssignableFrom(sClass)) {
                        // Get the mapper for the related DAO, if it has keys, it must be a foriegn object
                        if (graph.isForeignField(tName)) {
                            // look at foreign key fields, and make sure they are not null
                            List foreignKeys = graph.getForeignKeys(tName);
                            List foreignKeyValues = new ArrayList();
                            boolean nullKey = false;
                            for (Iterator k = foreignKeys.iterator(); k.hasNext(); ) {
                                String doProp = (String) k.next();
                                Object value = null;
                                PropertyDescriptor doPd = graph.getRealDomainFieldDescriptor(doProp);
                                if (doPd != null && doPd.getReadMethod() != null) {
                                    Method m = doPd.getReadMethod();
                                    if (!m.isAccessible())
                                        m.setAccessible(true);
                                    value = m.invoke(source, new Object[] {});
                                    if (value == null)
                                        nullKey = true;
                                    foreignKeyValues.add(value);
                                } else {
                                    throw new MouldException(MouldException.INVALID_FK_MAPPING, objectPath, doProp, graph.getDomainClassShortName());
                                }
                            }
                            if (nullKey) {
                                log.debug("Did not create skeleton object '" + tClass.getName() + "': one or more foreign key values missing.");
                            } else {
                                // Create the foreign object
                                log.debug("Creating foreign object - " + tClass.getName());
                                Object newDAO = newDAO(tClass);
                                boolean createSkeleton = true;
                                // Only retrieve related domain object and introspect if need
                                if (filter.areSubFieldsIncluded(fullName)) {
                                    // read object and introspect all
                                    log.debug("Read foreign object '" + fullName + "' and mold");
                                    try {
                                        Object sValue = sm.invoke(source, (Object[]) null);
                                        if (sValue != null) {
                                            BeanMoulder.moldFromDomain(sValue, newDAO, null, filter, fullName, true);
                                            createSkeleton = false;
                                        }
                                    } catch (InvocationTargetException e) {
                                        // If the foreign object is not found, warn and create the skeleton
                                        if (e.getCause() != null && e.getCause() instanceof InvalidForeignKeyException)
                                            log.warn("All foreign keys present, but foreign object does not exist");
                                        else
                                            throw e;
                                    }
                                }
                                if (createSkeleton) {
                                    // just set foreign keys from current object
                                    log.debug("Set keys on skeleton foreign object only");
                                    GraphMapping graph2 = MappingFactory.getInstance(newDAO);
                                    Set keys = graph2.getKeyFields();
                                    if (keys == null || keys.size() != foreignKeyValues.size()) {
                                        throw new MouldException(MouldException.MISMATCH_FK_MAPPING, objectPath, target.getClass().getName(), newDAO.getClass().getName());
                                    }
                                    int k2 = 0;
                                    // Look through all the foreign keys on the skeleton object
                                    for (Iterator k = keys.iterator(); k.hasNext(); k2++) {
                                        String keyField = (String) k.next();
                                        Object keyValue = foreignKeyValues.get(k2);
                                        PropertyDescriptor pd = graph2.getDataFieldDescriptor(keyField);
                                        if (pd != null && pd.getWriteMethod() != null) {
                                            Method m = pd.getWriteMethod();
                                            if (!m.isAccessible())
                                                m.setAccessible(true);
                                            m.invoke(newDAO, new Object[] { keyValue });
                                        } else {
                                            throw new MouldException(MouldException.CANT_SET_KEY_FIELD, objectPath, keyField, newDAO.getClass().getName());
                                        }
                                    }
                                }
                                tm.invoke(target, new Object[] { newDAO });
                                log.debug("Set " + tName + " = " + newDAO);
                            }
                        } else {
                            // This is not a foreign object, must be a related object
                            if (filter.areSubFieldsIncluded(fullName)) {
                                // Create the related object
                                log.debug("Creating One-To-One object - " + tClass.getName());
                                Object newDAO = newDAO(tClass);
                                // read object and introspect all
                                log.debug("Read related object '" + fullName + "' and mold");
                                Object sValue = sm.invoke(source, (Object[]) null);
                                if (sValue != null) {
                                    BeanMoulder.moldFromDomain(sValue, newDAO, null, filter, fullName, true);
                                } else {
                                    log.debug("Related object '" + fullName + "' not found. Ignore it!");
                                }
                                tm.invoke(target, new Object[] { newDAO });
                                log.debug("Set " + tName + " = " + newDAO);
                            } else
                                log.debug("No subfields for object " + fullName + " included. Object not retrieved");
                        }
                    // END-related object
                    // See if Target may be an array of DAO's
                    } else if (tClass.isArray() && DomainDAO.class.isAssignableFrom(tClass.getComponentType()) && filter.areSubFieldsIncluded(fullName)) {
                        log.debug("Target is an array of DAO's");
                        log.debug("Read related objects '" + fullName + "' and mold");
                        Object sValue = sm.invoke(source, (Object[]) null);
                        if (sClass.isArray() && IPersistent.class.isAssignableFrom(sClass.getComponentType())) {
                            log.debug("Source is an array of Persistent Objects");
                            Object[] sArray = (Object[]) sValue;
                            if (sArray.length > 0) {
                                Object[] tArray = (Object[]) Array.newInstance(tClass.getComponentType(), sArray.length);
                                log.debug("Translate Array of Size " + sArray.length);
                                for (int j = 0; j < sArray.length; j++) {
                                    Object newDAO = newDAO(tClass.getComponentType());
                                    BeanMoulder.moldFromDomain(sArray[j], newDAO, null, filter, fullName, false);
                                    tArray[j] = newDAO;
                                    log.debug("Add to array [" + j + "] : " + newDAO);
                                }
                                tm.invoke(target, new Object[] { (Object) tArray });
                                log.debug("Set Array " + tName);
                            } else
                                log.debug("Source Array is empty! Do Nothing");
                        }
                    // source is DO array
                    // Error... No way to map property
                    } else {
                        String err = "Can't Mold Property " + fullName + " from " + sClass.getName() + " to " + tClass.getName();
                        log.error(err);
                        throw new RuntimeException(err);
                    }
                }
            // is included in filtered fields
            }
        // Clear changed fields on updated DAO
        if (target != null && target instanceof DomainDAO)
            ((DomainDAO) target).clearChanges();
    } catch (IllegalAccessException e) {
        MouldException me = new MouldException(MouldException.ACCESS_ERROR, objectPath, e.getMessage());
        log.error(me.getLocalizedMessage(), e);
        throw me;
    } catch (InvocationTargetException e) {
        if (e.getCause() != null) {
            if (e.getCause() instanceof FrameworkException)
                throw (FrameworkException) e.getCause();
            if (e.getCause() instanceof ApplicationExceptions)
                throw (ApplicationExceptions) e.getCause();
            if (e.getCause() instanceof ApplicationException) {
                ApplicationExceptions aes = new ApplicationExceptions();
                aes.add((ApplicationException) e.getCause());
                throw aes;
            }
        }
        MouldException me = new MouldException(MouldException.INVOCATION_ERROR, objectPath, e);
        log.error(me.getLocalizedMessage(), me.getCause());
        throw me;
    } catch (InstantiationException e) {
        MouldException me = new MouldException(MouldException.INSTANTICATION_ERROR, objectPath, e.getMessage());
        log.error(me.getLocalizedMessage(), e);
        throw me;
    }
}
Also used : Set(java.util.Set) ArrayList(java.util.ArrayList) MappingFilter(org.jaffa.beans.moulding.mapping.MappingFilter) IPersistent(org.jaffa.persistence.IPersistent) Iterator(java.util.Iterator) DomainDAO(org.jaffa.beans.moulding.data.domain.DomainDAO) ArrayList(java.util.ArrayList) List(java.util.List) ApplicationExceptions(org.jaffa.exceptions.ApplicationExceptions) PropertyDescriptor(java.beans.PropertyDescriptor) FrameworkException(org.jaffa.exceptions.FrameworkException) InvalidForeignKeyException(org.jaffa.datatypes.exceptions.InvalidForeignKeyException) Method(java.lang.reflect.Method) InvocationTargetException(java.lang.reflect.InvocationTargetException) ApplicationException(org.jaffa.exceptions.ApplicationException) GraphMapping(org.jaffa.beans.moulding.mapping.GraphMapping)

Example 4 with DomainDAO

use of org.jaffa.beans.moulding.data.domain.DomainDAO in project jaffa-framework by jaffa-projects.

the class BeanMoulder method deleteBeanData.

private static void deleteBeanData(String path, DomainDAO source, UOW uow, MouldHandler handler, GraphMapping mapping, IPersistent domainObject) throws InstantiationException, IllegalAccessException, InvocationTargetException, ApplicationExceptions, FrameworkException {
    try {
        // Fire 'startBean' handler
        if (handler != null)
            handler.startBean(path, source, domainObject);
        // ----------------------------------------------------------------
        // Now loop through children, if there is one, delete it, and leave parent alone
        boolean deleteChild = false;
        // Reflect any related objects
        for (Iterator it = mapping.getRelatedFields().iterator(); it.hasNext(); ) {
            String field = (String) it.next();
            if (source.hasChanged(field)) {
                Object value = getProperty(mapping.getDataFieldDescriptor(field), source);
                if (value != null) {
                    if (value.getClass().isArray()) {
                        // The related field is an array of objects (one-to-many)
                        Object[] values = (Object[]) value;
                        for (int i = 0; i < values.length; i++) {
                            // Assumes its a DAO....what else could it be?
                            DomainDAO dao = (DomainDAO) values[i];
                            if (dao != null) {
                                deleteChild = true;
                                deleteChildBean(path + "." + field + "[" + i + "]", dao, uow, handler, domainObject, mapping, field);
                            }
                        }
                    } else {
                        // The related field is a single object (one-to-many)
                        // Assumes its a DAO....what else could it be?
                        DomainDAO dao = (DomainDAO) value;
                        deleteChild = true;
                        deleteChildBean(path + "." + field, dao, uow, handler, domainObject, mapping, field);
                    }
                }
            }
        }
        // Delete this record, as it had no children
        if (!deleteChild) {
            log.debug("UOW.Delete Domain Object");
            // Fire 'startBeanDelete' handler
            if (handler != null)
                handler.startBeanDelete(path, source, domainObject);
            uow.delete(domainObject);
            // Fire 'endBeanDelete' handler
            if (handler != null)
                handler.endBeanDelete(path, source, domainObject);
        }
        // Fire 'endBean' handler
        if (handler != null)
            handler.endBean(path, source, domainObject);
    } catch (ApplicationException e) {
        ApplicationExceptions aes = new ApplicationExceptions();
        aes.add(e);
        throw aes;
    }
}
Also used : ApplicationException(org.jaffa.exceptions.ApplicationException) ApplicationExceptions(org.jaffa.exceptions.ApplicationExceptions) Iterator(java.util.Iterator) DomainDAO(org.jaffa.beans.moulding.data.domain.DomainDAO)

Aggregations

DomainDAO (org.jaffa.beans.moulding.data.domain.DomainDAO)4 ArrayList (java.util.ArrayList)3 Iterator (java.util.Iterator)3 ApplicationException (org.jaffa.exceptions.ApplicationException)3 ApplicationExceptions (org.jaffa.exceptions.ApplicationExceptions)3 PropertyDescriptor (java.beans.PropertyDescriptor)2 InvocationTargetException (java.lang.reflect.InvocationTargetException)2 Method (java.lang.reflect.Method)2 List (java.util.List)2 Set (java.util.Set)2 GraphMapping (org.jaffa.beans.moulding.mapping.GraphMapping)2 BeanInfo (java.beans.BeanInfo)1 IntrospectionException (java.beans.IntrospectionException)1 MappingFilter (org.jaffa.beans.moulding.mapping.MappingFilter)1 InvalidForeignKeyException (org.jaffa.datatypes.exceptions.InvalidForeignKeyException)1 FrameworkException (org.jaffa.exceptions.FrameworkException)1 IPersistent (org.jaffa.persistence.IPersistent)1