BusinessObjectMetaDataServiceImpl.java :  » ERP-CRM-Financial » rice » org » kuali » core » service » impl » Java Open Source

Java Open Source » ERP CRM Financial » rice 
rice » org » kuali » core » service » impl » BusinessObjectMetaDataServiceImpl.java
/*
 * Copyright 2007 The Kuali Foundation.
 * 
 * Licensed under the Educational Community License, Version 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.opensource.org/licenses/ecl1.php
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.kuali.core.service.impl;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.kuali.core.bo.BusinessObject;
import org.kuali.core.bo.BusinessObjectRelationship;
import org.kuali.core.bo.PersistableBusinessObject;
import org.kuali.core.datadictionary.BusinessObjectEntry;
import org.kuali.core.datadictionary.CollectionDefinition;
import org.kuali.core.datadictionary.FieldDefinition;
import org.kuali.core.datadictionary.InquirySectionDefinition;
import org.kuali.core.datadictionary.PrimitiveAttributeDefinition;
import org.kuali.core.datadictionary.RelationshipDefinition;
import org.kuali.core.datadictionary.SupportAttributeDefinition;
import org.kuali.core.service.BusinessObjectDictionaryService;
import org.kuali.core.service.BusinessObjectMetaDataService;
import org.kuali.core.service.DataDictionaryService;
import org.kuali.core.service.PersistenceStructureService;
import org.kuali.core.util.ObjectUtils;

/**
 * 
 * Implementation of the <code>BusinessObjectMetaDataService</code> which uses the following
 * services to gather its meta data:
 * @see BusinessObjectDictionaryService
 * @see DataDictionaryService
 * @see PersistenceStructureService
 */
public class BusinessObjectMetaDataServiceImpl implements BusinessObjectMetaDataService {
    private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(BusinessObjectMetaDataServiceImpl.class);

    private BusinessObjectDictionaryService businessObjectDictionaryService;
    private DataDictionaryService dataDictionaryService;
    private PersistenceStructureService persistenceStructureService;

    public Collection<String> getCollectionNames(BusinessObject bo) {
        Map<String, CollectionDefinition> collections = dataDictionaryService.getDataDictionary()
            .getBusinessObjectEntry(bo.getClass().getName()).getCollections();
        
        return collections.keySet();
    }

    public Collection<String> getInquirableFieldNames(Class boClass, String sectionTitle) {
        return businessObjectDictionaryService.getInquiryFieldNames(boClass, sectionTitle);
    }
    
    public List<String> getLookupableFieldNames(Class boClass) {
        return businessObjectDictionaryService.getLookupFieldNames(boClass);
    }

    public String getLookupFieldDefaultValue(Class businessObjectClass, String attributeName) {
        return businessObjectDictionaryService.getLookupFieldDefaultValue(businessObjectClass, attributeName);
    }

    public Class getLookupFieldDefaultValueFinderClass(Class businessObjectClass, String attributeName) {
        return businessObjectDictionaryService.getLookupFieldDefaultValueFinderClass(businessObjectClass, attributeName);
    }

    public boolean isAttributeInquirable(Class boClass, String attributeName, String sectionTitle) {
        Collection sections = businessObjectDictionaryService.getInquirySections(boClass);
        boolean isInquirable = true;
        
        Iterator iter = sections.iterator();
       
        while(iter.hasNext()) {
            InquirySectionDefinition def = (InquirySectionDefinition)iter.next();
            for(FieldDefinition field : def.getInquiryFields()) {
                if(field.getAttributeName().equalsIgnoreCase(attributeName)) {
                    isInquirable = !field.isNoInquiry();
                }
            }
        }
        if(isInquirable) {
            Object obj = null;
            if(boClass != null && BusinessObject.class.isAssignableFrom(boClass)) {
                obj = ObjectUtils.createNewObjectFromClass(boClass); 
            }
            
            
            if(obj != null) {
                BusinessObject bo = (BusinessObject)obj;
                Class clazz = getNestedBOClass(bo, attributeName);
                if(clazz != null && BusinessObject.class.isAssignableFrom(clazz)) {
                    return businessObjectDictionaryService.isInquirable(clazz);
                }
                else {
                    return false;
                }
            } else {
                return false;
            }
            
        }
        
        return isInquirable;
    }

    public boolean isInquirable(Class boClass) {
        return businessObjectDictionaryService.isInquirable(boClass);
    }
    
    public boolean isAttributeLookupable(Class boClass, String attributeName) {
        Object obj = null;
        if(boClass != null && BusinessObject.class.isAssignableFrom(boClass)) {
            obj = ObjectUtils.createNewObjectFromClass(boClass); 
        }
        if(obj != null) {
            BusinessObject bo = (BusinessObject)obj;
            BusinessObjectRelationship relationship = getBusinessObjectRelationship(bo, attributeName);
            
            if(relationship != null && relationship.getRelatedClass() != null && BusinessObject.class.isAssignableFrom(relationship.getRelatedClass())) {
                return isLookupable(relationship.getRelatedClass());
            }
            else {
                return false;
            }
        }
        else {
            return false;
        }
    }
    
    public boolean isLookupable(Class boClass) {
        boolean lookupable = false;
        Boolean isLookupable = businessObjectDictionaryService.isLookupable(boClass);
        if(isLookupable != null) {
            lookupable = isLookupable.booleanValue();
        }
        return lookupable;
    }
    public BusinessObjectRelationship getBusinessObjectRelationship(BusinessObject bo, String attributeName ) {
        return getBusinessObjectRelationship( bo, bo.getClass(), attributeName, "", true );
    }
    
    public BusinessObjectRelationship getBusinessObjectRelationship(RelationshipDefinition ddReference, BusinessObject bo, Class boClass, String attributeName, String attributePrefix, boolean keysOnly ) {
        
        BusinessObjectRelationship relationship = null;
        
        //if it is nested then replace the bo and attributeName with the sub-refs
        if(ObjectUtils.isNestedAttribute(attributeName)) {
            if ( ddReference != null ) {
                relationship = new BusinessObjectRelationship(boClass, ddReference.getObjectAttributeName(), ddReference.getTargetClass() );
                for ( PrimitiveAttributeDefinition def : ddReference.getPrimitiveAttributes() ) {
                    if ( StringUtils.isNotBlank( attributePrefix ) ) {
                        relationship.getParentToChildReferences().put( attributePrefix + "." + def.getSourceName(), def.getTargetName() );
                    } else {
                        relationship.getParentToChildReferences().put( def.getSourceName(), def.getTargetName() );
                    }
                }
                if ( !keysOnly ) {
                    for ( SupportAttributeDefinition def : ddReference.getSupportAttributes() ) {
                        if ( StringUtils.isNotBlank( attributePrefix ) ) {
                            relationship.getParentToChildReferences().put( attributePrefix + "." + def.getSourceName(), def.getTargetName() );
                          if ( def.isIdentifier() ) {
                            relationship.setUserVisibleIdentifierKey( attributePrefix + "." + def.getSourceName() );
                          }
                        } else {
                            relationship.getParentToChildReferences().put( def.getSourceName(), def.getTargetName() );
                          if ( def.isIdentifier() ) {
                            relationship.setUserVisibleIdentifierKey( def.getSourceName() );
                          }
                        }
                    }
                }
                return relationship;
            }
            // recurse down to the next object to find the relationship

            String localPrefix = StringUtils.substringBefore( attributeName, "." );
            String localAttributeName = StringUtils.substringAfter(attributeName, ".");
            if ( bo == null ) {
              bo = (BusinessObject)ObjectUtils.createNewObjectFromClass( boClass );
            }
            Class nestedClass = ObjectUtils.getPropertyType( bo, localPrefix, getPersistenceStructureService() );
            String fullPrefix = localPrefix;
            if ( StringUtils.isNotBlank( attributePrefix ) ) {
                fullPrefix = attributePrefix + "." + localPrefix; 
            }
            if(BusinessObject.class.isAssignableFrom(nestedClass)) {
                relationship = getBusinessObjectRelationship( null, nestedClass, localAttributeName, fullPrefix, keysOnly );                    
            }
            return relationship;
        }
        
        //try persistable reference first
        if(PersistableBusinessObject.class.isAssignableFrom( boClass )) {
            Map<String,BusinessObjectRelationship> rels = persistenceStructureService.getRelationshipMetadata( boClass, attributeName, attributePrefix );
            if ( rels.size() > 0 ) {
                int maxSize = 255;
                for ( BusinessObjectRelationship rel : rels.values() ) {
                    if ( rel.getParentToChildReferences().size() < maxSize && isLookupable( rel.getRelatedClass() ) ) {
                        maxSize = rel.getParentToChildReferences().size();
                        relationship = rel;
                    }
                }
            }
        }

        //then check the DD for relationships defined there
        //TODO move out to a separate method
        //so that the logic for finding the relationships is similar to primitiveReference
        if ( relationship == null ) {
            if(ddReference != null && isLookupable( ddReference.getTargetClass() ) ) {
                relationship = new BusinessObjectRelationship(bo.getClass(), ddReference.getObjectAttributeName(), ddReference.getTargetClass() );
                for ( PrimitiveAttributeDefinition def : ddReference.getPrimitiveAttributes() ) {
                    relationship.getParentToChildReferences().put( def.getSourceName(), def.getTargetName() );
                }
                if ( !keysOnly ) {
                    for ( SupportAttributeDefinition def : ddReference.getSupportAttributes() ) {
                        relationship.getParentToChildReferences().put( def.getSourceName(), def.getTargetName() );
                    }
                }
            }
        }

        return relationship;
        
    }
    
    public RelationshipDefinition getBusinessObjectRelationshipDefinition(Class c, String attributeName) {
        return getDDRelationship(c, attributeName);
    }
    
    public RelationshipDefinition getBusinessObjectRelationshipDefinition(BusinessObject bo, String attributeName) {
        return getBusinessObjectRelationshipDefinition(bo.getClass(), attributeName);
    }
    
    public BusinessObjectRelationship getBusinessObjectRelationship(BusinessObject bo, Class boClass, String attributeName, String attributePrefix, boolean keysOnly ) {
        RelationshipDefinition ddReference = getBusinessObjectRelationshipDefinition(boClass, attributeName);
        return getBusinessObjectRelationship(ddReference, bo, boClass, attributeName, attributePrefix, keysOnly);
    }

    

    /**
     * Gets the dataDictionaryService attribute. 
     * @return Returns the dataDictionaryService.
     */
    public DataDictionaryService getDataDictionaryService() {
        return dataDictionaryService;
    }

    /**
     * Sets the dataDictionaryService attribute value.
     * @param dataDictionaryService The dataDictionaryService to set.
     */
    public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
        this.dataDictionaryService = dataDictionaryService;
    }

    /**
     * Gets the businessObjectDictionaryService attribute. 
     * @return Returns the businessObjectDictionaryService.
     */
    public BusinessObjectDictionaryService getBusinessObjectDictionaryService() {
        return businessObjectDictionaryService;
    }

    /**
     * Sets the businessObjectDictionaryService attribute value.
     * @param businessObjectDictionaryService The BusinessObjectDictionaryService to set.
     */
    public void setBusinessObjectDictionaryService(BusinessObjectDictionaryService businessObjectDictionaryService) {
        this.businessObjectDictionaryService = businessObjectDictionaryService;
    }

    /**
     * Gets the persistenceStructureService attribute. 
     * @return Returns the persistenceStructureService.
     */
    public PersistenceStructureService getPersistenceStructureService() {
        return persistenceStructureService;
    }

    /**
     * Sets the persistenceStructureService attribute value.
     * @param persistenceStructureService The persistenceStructureService to set.
     */
    public void setPersistenceStructureService(PersistenceStructureService persistenceStructureService) {
        this.persistenceStructureService = persistenceStructureService;
    }

    /**
     * 
     * This method retrieves the business object class for a specific attribute
     * @param bo
     * @param attributeName
     * @return a business object class for a specific attribute
     */
    private Class getNestedBOClass(BusinessObject bo, String attributeName) {

        String[] nestedAttributes = StringUtils.split(attributeName, ".");
        String attributeRefName = "";
        Class clazz = null;
        if (nestedAttributes.length > 1) {
            String attributeStringSoFar = "";
            for (int i = 0; i < nestedAttributes.length - 1; i++) {
                try {
                    // we need to build a string of the attribute names depending on which iteration we're in.
                    // so if the original attributeName string we're using is "a.b.c.d.e", then first iteration would use
                    // "a", 2nd "a.b", 3rd "a.b.c", etc.
                    if (i != 0) {
                        attributeStringSoFar = attributeStringSoFar + ".";  
                    }
                    attributeStringSoFar = attributeStringSoFar + nestedAttributes[i];
                    clazz = ObjectUtils.easyGetPropertyType(bo, attributeStringSoFar);
                } catch(InvocationTargetException ite) {
                    LOG.info(ite);
                    return null;
                } catch(NoSuchMethodException nsme) {
                    LOG.info(nsme);
                    return null;
                } catch(IllegalAccessException iae) {
                    LOG.info(iae);
                    return null;
                }
            }
        } 
        return clazz;
    }
    
    
    
        
    public RelationshipDefinition getDDRelationship(Class c, String attributeName) {
        BusinessObjectEntry entryBase = dataDictionaryService.getDataDictionary().getBusinessObjectEntry(c.getName());
        if(entryBase ==null) {
            return null;
        }

        Map<String, RelationshipDefinition> ddRelationships = entryBase.getRelationships();
        RelationshipDefinition relationship = null;
        int minKeys = Integer.MAX_VALUE;
        for(String key : ddRelationships.keySet()) {
            RelationshipDefinition def = ddRelationships.get(key);
            //favor key sizes of 1 first
            if(def.getPrimitiveAttributes().size() == 1) {
                for(PrimitiveAttributeDefinition primitive : def.getPrimitiveAttributes()) {
                    if(primitive.getSourceName().equals(attributeName)||def.getObjectAttributeName().equals(attributeName)) {
                        relationship = def;
                        minKeys = 1;
                        break;
                    }
                }   
            } else if(def.getPrimitiveAttributes().size() < minKeys) {
                for(PrimitiveAttributeDefinition primitive : def.getPrimitiveAttributes()) {
                    if(primitive.getSourceName().equals(attributeName)||def.getObjectAttributeName().equals(attributeName)) {
                        relationship = def;
                        minKeys = def.getPrimitiveAttributes().size();
                        break;
                    }
                }
            }
        }
        // check the support attributes
        if ( relationship == null ) {
            for ( RelationshipDefinition def : ddRelationships.values() ) {
                if ( def.hasIdentifier() ) {
                    if ( def.getIdentifier().getSourceName().equals(attributeName) ) {
                        relationship = def;
                    }
                }
            }
        }
        return relationship;
    }
    

    public List<BusinessObjectRelationship> getBusinessObjectRelationships(BusinessObject bo) {
        if ( bo == null ) return null;
        
        Map<String,Class> referenceClasses = null;
        if ( bo instanceof PersistableBusinessObject ) {
            referenceClasses = getPersistenceStructureService().listReferenceObjectFields( bo.getClass() );
        }
        Map<String, RelationshipDefinition> ddRelationships = dataDictionaryService.getDataDictionary().getDictionaryObjectEntry(bo.getClass().getName()).getRelationships();
        List<BusinessObjectRelationship> relationships = new ArrayList<BusinessObjectRelationship>();
        
        // loop over all relationships
        if ( referenceClasses != null ) {
            for ( Map.Entry<String,Class> entry : referenceClasses.entrySet() ) {
                if ( isLookupable( entry.getValue() ) ) { 
                    Map<String,String> fkToPkRefs = persistenceStructureService.getForeignKeysForReference( bo.getClass(), entry.getKey() );
                    BusinessObjectRelationship rel = new BusinessObjectRelationship( bo.getClass(), entry.getKey(), entry.getValue() );
                    for ( Map.Entry<String,String> ref : fkToPkRefs.entrySet() ) {
                        rel.getParentToChildReferences().put( ref.getKey(), ref.getValue() );
                    }
                    
                    relationships.add( rel );
                }
            }
        }
        
        for ( RelationshipDefinition rd : ddRelationships.values() ) {
            if ( isLookupable( rd.getTargetClass() ) ) {
                BusinessObjectRelationship rel = new BusinessObjectRelationship( bo.getClass(), rd.getObjectAttributeName(), rd.getTargetClass() );
                for ( PrimitiveAttributeDefinition def : rd.getPrimitiveAttributes() ) {
                    rel.getParentToChildReferences().put( def.getSourceName(), def.getTargetName() );
                }
                relationships.add( rel );
            }
        }
        
        
        return relationships;
    }
    
    
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.