Package er.extensions.components

Source Code of er.extensions.components.ERXGroupingRepetition

/*
* Copyright (C) NetStruxr, Inc. All rights reserved.
*
* This software is published under the terms of the NetStruxr
* Public Software License version 0.5, a copy of which has been
* included with this distribution in the LICENSE.NPL file.  */
package er.extensions.components;

import java.util.Enumeration;

import org.apache.log4j.Logger;

import com.webobjects.appserver.WOContext;
import com.webobjects.foundation.NSArray;
import com.webobjects.foundation.NSKeyValueCoding;
import com.webobjects.foundation.NSKeyValueCodingAdditions;
import com.webobjects.foundation.NSMutableArray;
import com.webobjects.foundation.NSMutableDictionary;

/**
* Groups items into sections.For example: Employees belong to a department, you want to
* group on department. So the parent will need to consist of something like:
* <pre>
*
* [erxgroupingrepetition]
* [wostring value=currentDepartment.name]
* [worepetition list=currentEmployees item=currentEmployee]
*    [wostring value=currentEmployees.firstName]
* [/worepetition]
* [/erxgroupingrepetition]
*
* </pre>
* and then you'd set up the bindings of the grouping repetition like:
* <pre>
*
* list=allEmployees : list of employees to group
* item=currentEmployee : will be set so the next key can get evaluated
* sectionForItem=departmentForCurrentEmployee : a method in the parent that returns sth like currentEmployee.department()
* sectionKey="name" : assuming department has a name, but can be unbound; note that you can group on "city", too!
* subListSection=currentDepartment : instance variable in the parent that will get set to the current department
* subList=currentEmployees : instance variable in the parent that will get set to the employees of the current department
* sortKey="@sortAsc.name" : sorts the department list by name
*
* </pre>
* If a user could belong to many departments, you could either set the <code>splitArrays</code> binding to true,
* in which case the sections would be all the departments and the user would be added in each section he belongs
* or you could leave it out. Then the sections will be each combination of departments a user belongs to.
* Please see the page BugsPerUser.wo from the BugTracker application to find another example on how to use it.
* @binding list list of objects to group
* @binding item current item, will get pushed to the parent, so that it can evaluate sectionForItem
* @binding sectionForItem value pulled from the parent, after "item" gets pushed
* @binding sectionKey key to group departments on (usually primaryKey or hashCode)
* @binding subListSection will get set to the current section
* @binding subList will get set to the grouped items for the section
* @binding sortKey optional key for sorting the group list (sth like '@sortAsc.name')
* @binding splitArrays optional boolean specifying if array keys are regarded as distinct keys
* @binding ignoreNulls optional boolean specifying if nulls are ignored
*/

public class ERXGroupingRepetition extends ERXStatelessComponent {
  /**
   * Do I need to update serialVersionUID?
   * See section 5.6 <cite>Type Changes Affecting Serialization</cite> on page 51 of the
   * <a href="http://java.sun.com/j2se/1.4/pdf/serial-spec.pdf">Java Object Serialization Spec</a>
   */
  private static final long serialVersionUID = 1L;

    public ERXGroupingRepetition(WOContext aContext) {
        super(aContext);
    }

    /** logging support */
    public static final Logger log = Logger.getLogger(ERXGroupingRepetition.class);
   
    private NSMutableArray _sections;
    private Object _sectionItem;
    private NSMutableDictionary _itemsPerSection=new NSMutableDictionary();
    private final static Object NULL="N/A";
   
    private String _sectionKey;
    public String sectionKey() {
        if (_sectionKey==null) {
            _sectionKey=stringValueForBinding("sectionKey", "hashCode");
        }
        return _sectionKey;
    }
   
    public NSArray sections() {
        if (_sections==null) {
            _sections= new NSMutableArray();
            NSArray list=(NSArray)valueForBinding("list");
            _itemsPerSection=new NSMutableDictionary();
            if (list!=null) {
                boolean ignoreNulls = booleanValueForBinding("ignoreNulls", false);
               
                for (Enumeration e=list.objectEnumerator(); e.hasMoreElements();) {
                    Object item=e.nextElement();
                    if(log.isDebugEnabled()) log.debug("item = "+item);
                   
                    // push value up, so parent can tell us the group
                    setValueForBinding(item,"item");
                   
                    // Sections have to be copiable objects -- no EOs!!
                    Object section=valueForBinding("sectionForItem");
                    if (section==NSKeyValueCoding.NullValue) section=null;
                    Object sectionKey;

                    if(section == null) {
                        if(ignoreNulls) {
                            continue;
                        }
                        section=NULL;
                    }
                    sectionKey = keyForSection(section);
                    if(sectionKey instanceof NSArray) {
                        NSArray array = (NSArray)sectionKey;
                        int index = 0;
                        for (Enumeration keys = ((NSArray)sectionKey).objectEnumerator(); keys.hasMoreElements(); ) {
                            Object currentKey = keys.nextElement();
                            Object currentSection = ((NSArray)section).objectAtIndex(index++);
                            NSMutableArray currentItemsForSection=(NSMutableArray)_itemsPerSection.objectForKey(currentKey);
                            if (currentItemsForSection==null) {
                                _sections.addObject(currentSection);
                                currentItemsForSection=new NSMutableArray();
                                _itemsPerSection.setObjectForKey(currentItemsForSection,currentKey);
                            }
                            currentItemsForSection.addObject(item);
                        }
                    } else {
                        NSMutableArray currentItemsForSection=(NSMutableArray)_itemsPerSection.objectForKey(sectionKey);
                        if (currentItemsForSection==null) {
                            _sections.addObject(section);
                            currentItemsForSection=new NSMutableArray();
                            _itemsPerSection.setObjectForKey(currentItemsForSection,sectionKey);
                        }
                        currentItemsForSection.addObject(item);
                    }
                }
            }
            String sortKey = (String)valueForBinding("sortKey");
            //the key act on the array, so it must be in the form "@sortAsc.someKey"
            if(sortKey != null) {
                _sections = (NSMutableArray)_sections.valueForKeyPath(sortKey);
            }
        }
        return _sections;
    }
   
    /**
     * @param splitArrays
     * @param section
     */
    private Object keyForSection(Object section) {
        Object sectionKey = NULL;
        if(section != null && section != NULL) {
            sectionKey = NSKeyValueCodingAdditions.Utility.valueForKeyPath(section,sectionKey());
            if(!splitArrays() && (sectionKey instanceof NSArray)) {
                sectionKey = ((NSArray)((NSArray)section).valueForKey(_sectionKey)).componentsJoinedByString(",");
            }
        }
        return sectionKey;
    }

   
    private Boolean _splitArrays;
    private boolean splitArrays() {
        if(_splitArrays == null) {
            _splitArrays = booleanValueForBinding("splitArrays", false) ? Boolean.TRUE : Boolean.FALSE;
        }
        return _splitArrays.booleanValue();
    }

    public Object sectionItem() {
        return _sectionItem;
    }
   
    public void setSectionItem(Object section) {
        _sectionItem=section;
        setValueForBinding(_sectionItem!=NULL ? _sectionItem : null, "subListSection");
        setValueForBinding(_itemsPerSection.objectForKey(keyForSection(_sectionItem)), "subList");
    }
   
    @Override
    public void reset() {
        _sections=null;
        _splitArrays=null;
        _sectionItem=null;
        _sectionKey=null;
        _itemsPerSection=null;
    }
}
TOP

Related Classes of er.extensions.components.ERXGroupingRepetition

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.