Example usage for java.util Stack pop

List of usage examples for java.util Stack pop

Introduction

In this page you can find the example usage for java.util Stack pop.

Prototype

public synchronized E pop() 

Source Link

Document

Removes the object at the top of this stack and returns that object as the value of this function.

Usage

From source file:org.sakaiproject.signup.tool.entityproviders.SignupEntityProducer.java

@SuppressWarnings("unchecked")
@Override//from  www  .j  a  v a2  s . co m
public String archive(String siteId, Document doc, Stack stack, String archivePath, List attachments) {

    String currentUserId = getSakaiFacade().getCurrentUserId();
    StringBuilder results = new StringBuilder();

    results.append("archiving " + getLabel() + Entity.SEPARATOR + siteId + Entity.SEPARATOR
            + SiteService.MAIN_CONTAINER + ".\n");

    Element rootElement = doc.createElement(SignupMeetingService.class.getName());
    ((Element) stack.peek()).appendChild(rootElement); //<org.sakaiproject>
    stack.push(rootElement);

    List<SignupMeeting> allMeetings = getSignupMeetingService().getAllSignupMeetings(siteId, currentUserId);

    if (allMeetings.size() > 0) {
        Element meetingListElement = this.copyFileProcessor.toXml("meetingList", doc, stack); //<meetingList>

        //adds meetings
        for (int i = 0; allMeetings.size() > i; i++) {
            try {
                SignupMeeting meeting = allMeetings.get(i);

                Element meetingElement = this.copyFileProcessor.toXml("meeting", doc, stack); //<meeting>
                Element titleElement = this.copyFileProcessor.toXml("title", doc, stack); //<title>
                Element locElement = this.copyFileProcessor.toXml("location", doc, stack); //<location>
                Element descElement = this.copyFileProcessor.toXml("description", doc, stack); //<description>
                Element meetingTypeElement = this.copyFileProcessor.toXml("meetingType", doc, stack); //<meetingType>
                Element creatorIdElement = this.copyFileProcessor.toXml("creatorId", doc, stack); //<creatorId>

                titleElement.appendChild(doc.createTextNode(meeting.getTitle())); //title
                locElement.appendChild(doc.createTextNode(meeting.getLocation())); //location
                descElement.appendChild(doc.createTextNode(meeting.getDescription())); //description
                meetingTypeElement.appendChild(doc.createTextNode(meeting.getMeetingType())); //meetingType
                creatorIdElement.appendChild(doc.createTextNode(meeting.getCreatorUserId())); //creatorId

                meetingElement.appendChild(titleElement);
                meetingElement.appendChild(locElement);
                meetingElement.appendChild(descElement);
                meetingElement.appendChild(meetingTypeElement);
                meetingElement.appendChild(creatorIdElement);

                if (meeting.isRecurredMeeting()) {
                    Element recurElement = this.copyFileProcessor.toXml("recurrenceType", doc, stack); //<recurrenceType>
                    recurElement.appendChild(doc.createTextNode(meeting.getRepeatType())); //recurrence
                    meetingElement.appendChild(recurElement);
                }

                Element timeslotListElement = this.copyFileProcessor.toXml("timeslotList", doc, stack); //<timeslotList>
                meetingElement.appendChild(timeslotListElement);

                List<SignupTimeslot> timeslots = meeting.getSignupTimeSlots(); //get the timeslots

                //adds timeslots to timeslotList
                for (int j = 0; j < timeslots.size(); j++) {
                    SignupTimeslot timeslot = timeslots.get(j);
                    List<SignupAttendee> attendees = timeslot.getAttendees();

                    Element timeslotElement = CopyFileProcessor.timeslotToXml(timeslot, doc, stack); //<timeslot>
                    timeslotListElement.appendChild(timeslotElement);

                    if (attendees.size() > 0) {
                        Element attendeeListElement = this.copyFileProcessor.toXml("attendeeList", doc, stack); //<attendeeList>
                        timeslotElement.appendChild(attendeeListElement);

                        //adds attendees and attendeeIds
                        for (int q = 0; q < attendees.size(); q++) {
                            SignupAttendee attendee = (SignupAttendee) attendees.get(q);
                            Element attendeeElement = this.copyFileProcessor.toXml("attendee", doc, stack); //<attendee>
                            Element attendeeIdElement = this.copyFileProcessor.toXml("attendeeId", doc, stack); //<attendeeId>
                            Element attendeeSiteIdElement = this.copyFileProcessor.toXml("attendeeSiteId", doc,
                                    stack); //<attendeeSiteId>

                            attendeeIdElement.appendChild(doc.createTextNode(attendee.getAttendeeUserId()));
                            attendeeSiteIdElement.appendChild(doc.createTextNode(attendee.getSignupSiteId()));
                            attendeeElement.appendChild(attendeeIdElement);
                            attendeeElement.appendChild(attendeeSiteIdElement);
                            attendeeListElement.appendChild(attendeeElement);
                        } //attendee loop end
                    } //if any attendee end
                } //timeslot loop end

                //if there are any attachments
                if (meeting.hasSignupAttachments()) {
                    Element attachmentListElement = this.copyFileProcessor.toXml("attachmentList", doc, stack); //<attachmentList>
                    List<SignupAttachment> allAttachments = meeting.getSignupAttachments();
                    meetingElement.appendChild(attachmentListElement);

                    //adds attachments
                    for (int m = 0; m < allAttachments.size(); m++) {
                        SignupAttachment attachment = allAttachments.get(m);

                        Element attachmentElement = this.copyFileProcessor.toXml("attachment", doc, stack); //<attachment>
                        Element attachmentUrlElement = this.copyFileProcessor.toXml("attachmentUrl", doc,
                                stack); //<attachmentUrl>
                        Element attachmentName = this.copyFileProcessor.toXml("attachmentName", doc, stack); //<attachmentName>
                        attachmentUrlElement.appendChild(doc.createTextNode(attachment.getResourceId()));
                        attachmentName.appendChild(doc.createTextNode(attachment.getFilename()));
                        attachmentElement.appendChild(attachmentUrlElement);
                        attachmentElement.appendChild(attachmentName);
                        attachmentListElement.appendChild(attachmentElement);
                    }
                }

                List<SignupSite> allSitesInMeeting = meeting.getSignupSites();

                Element availableToElement = this.copyFileProcessor.toXml("availableTo", doc, stack); //<availableTo>
                Element siteListElement = this.copyFileProcessor.toXml("siteList", doc, stack); //<siteList>
                availableToElement.appendChild(siteListElement);
                meetingElement.appendChild(availableToElement);

                for (int n = 0; n < allSitesInMeeting.size(); n++) {
                    SignupSite site = allSitesInMeeting.get(n);

                    Element siteElement = this.copyFileProcessor.toXml("site", doc, stack); //<site>
                    Element siteIdElement = this.copyFileProcessor.toXml("siteId", doc, stack); //<siteId>
                    siteIdElement.appendChild(doc.createTextNode(site.getSiteId()));
                    siteElement.appendChild(siteIdElement);
                    siteListElement.appendChild(siteElement);

                    //if there are groups
                    if (site.getSignupGroups().size() > 0) {
                        List<SignupGroup> allGroupsInSite = site.getSignupGroups();
                        Element groupListElement = this.copyFileProcessor.toXml("groupList", doc, stack); //<groupList>
                        siteElement.appendChild(groupListElement);

                        //adds groups
                        for (int g = 0; g < allGroupsInSite.size(); g++) {
                            SignupGroup group = allGroupsInSite.get(g);

                            Element groupElement = this.copyFileProcessor.toXml("group", doc, stack); //<group>
                            Element groupIdElement = this.copyFileProcessor.toXml("groupId", doc, stack); //<groupId>

                            groupIdElement.appendChild(doc.createTextNode(group.getGroupId()));
                            groupElement.appendChild(groupIdElement);
                            groupListElement.appendChild(groupElement);
                        }
                    } //signupGroups if end
                } //allSites for-loop end

                //add meetings to root
                meetingListElement.appendChild(meetingElement);
                rootElement.appendChild(meetingListElement);

            } catch (Exception e) {
                log.warn(e.getMessage());
            }
        } //main for-loop end
    }
    stack.pop();
    return results.toString();
}

From source file:org.alfresco.repo.domain.node.AbstractNodeDAOImpl.java

/**
 * Build the paths for a node// www  .  j a va  2 s  .co m
 * 
 * @param currentNodePair       the leave or child node to start with
 * @param currentRootNodePair   pass in <tt>null</tt> only 
 * @param currentPath           an empty {@link Path}
 * @param completedPaths        completed paths i.e. the result
 * @param assocIdStack          a stack to detected cyclic relationships
 * @param primaryOnly           <tt>true</tt> to follow only primary parent associations
 * @throws CyclicChildRelationshipException
 */
private void prependPaths(Pair<Long, NodeRef> currentNodePair, Pair<StoreRef, NodeRef> currentRootNodePair,
        Path currentPath, Collection<Path> completedPaths, Stack<Long> assocIdStack, boolean primaryOnly)
        throws CyclicChildRelationshipException {
    if (isDebugEnabled) {
        logger.debug("\n" + "Prepending paths: \n" + "   Current node: " + currentNodePair + "\n"
                + "   Current root: " + currentRootNodePair + "\n" + "   Current path: " + currentPath);
    }
    Long currentNodeId = currentNodePair.getFirst();
    NodeRef currentNodeRef = currentNodePair.getSecond();

    // Check if we have changed root nodes
    StoreRef currentStoreRef = currentNodeRef.getStoreRef();
    if (currentRootNodePair == null || !currentStoreRef.equals(currentRootNodePair.getFirst())) {
        // We've changed stores
        Pair<Long, NodeRef> rootNodePair = getRootNode(currentStoreRef);
        currentRootNodePair = new Pair<StoreRef, NodeRef>(currentStoreRef, rootNodePair.getSecond());
    }

    // get the parent associations of the given node
    ParentAssocsInfo parentAssocInfo = getParentAssocsCached(currentNodeId); // note: currently may throw NotLiveNodeException
    // bulk load parents as we are certain to hit them in the next call
    ArrayList<Long> toLoad = new ArrayList<Long>(parentAssocInfo.getParentAssocs().size());
    for (Map.Entry<Long, ChildAssocEntity> entry : parentAssocInfo.getParentAssocs().entrySet()) {
        toLoad.add(entry.getValue().getParentNode().getId());
    }
    cacheNodesById(toLoad);

    // does the node have parents
    boolean hasParents = parentAssocInfo.getParentAssocs().size() > 0;
    // does the current node have a root aspect?

    // look for a root. If we only want the primary root, then ignore all but the top-level root.
    if (!(primaryOnly && hasParents) && parentAssocInfo.isRoot()) // exclude primary search with parents present
    {
        // create a one-sided assoc ref for the root node and prepend to the stack
        // this effectively spoofs the fact that the current node is not below the root
        // - we put this assoc in as the first assoc in the path must be a one-sided
        // reference pointing to the root node
        ChildAssociationRef assocRef = new ChildAssociationRef(null, null, null,
                currentRootNodePair.getSecond());
        // create a path to save and add the 'root' assoc
        Path pathToSave = new Path();
        Path.ChildAssocElement first = null;
        for (Path.Element element : currentPath) {
            if (first == null) {
                first = (Path.ChildAssocElement) element;
            } else {
                pathToSave.append(element);
            }
        }
        if (first != null) {
            // mimic an association that would appear if the current node was below the root node
            // or if first beneath the root node it will make the real thing
            ChildAssociationRef updateAssocRef = new ChildAssociationRef(
                    parentAssocInfo.isStoreRoot() ? ContentModel.ASSOC_CHILDREN : first.getRef().getTypeQName(),
                    currentRootNodePair.getSecond(), first.getRef().getQName(), first.getRef().getChildRef());
            Path.Element newFirst = new Path.ChildAssocElement(updateAssocRef);
            pathToSave.prepend(newFirst);
        }

        Path.Element element = new Path.ChildAssocElement(assocRef);
        pathToSave.prepend(element);

        // store the path just built
        completedPaths.add(pathToSave);
    }

    // walk up each parent association
    for (Map.Entry<Long, ChildAssocEntity> entry : parentAssocInfo.getParentAssocs().entrySet()) {
        Long assocId = entry.getKey();
        ChildAssocEntity assoc = entry.getValue();
        ChildAssociationRef assocRef = assoc.getRef(qnameDAO);
        // do we consider only primary assocs?
        if (primaryOnly && !assocRef.isPrimary()) {
            continue;
        }
        // Ordering is meaningless here as we are constructing a path upwards
        // and have no idea where the node comes in the sibling order or even
        // if there are like-pathed siblings.
        assocRef.setNthSibling(-1);
        // build a path element
        Path.Element element = new Path.ChildAssocElement(assocRef);
        // create a new path that builds on the current path
        Path path = new Path();
        path.append(currentPath);
        // prepend element
        path.prepend(element);
        // get parent node pair
        Pair<Long, NodeRef> parentNodePair = new Pair<Long, NodeRef>(assoc.getParentNode().getId(),
                assocRef.getParentRef());

        // does the association already exist in the stack
        if (assocIdStack.contains(assocId)) {
            // the association was present already
            logger.error("Cyclic parent-child relationship detected: \n" + "   current node: " + currentNodeId
                    + "\n" + "   current path: " + currentPath + "\n" + "   next assoc: " + assocId);
            throw new CyclicChildRelationshipException("Node has been pasted into its own tree.", assocRef);
        }

        if (isDebugEnabled) {
            logger.debug("\n" + "   Prepending path parent: \n" + "      Parent node: " + parentNodePair);
        }

        // push the assoc stack, recurse and pop
        assocIdStack.push(assocId);

        prependPaths(parentNodePair, currentRootNodePair, path, completedPaths, assocIdStack, primaryOnly);

        assocIdStack.pop();
    }
    // done
}

From source file:com.zimbra.cs.account.ldap.LdapProvisioning.java

private List<DistributionList> getContainingDistributionLists(Entry entry, boolean directOnly,
        Map<String, String> via) throws ServiceException {
    List<DistributionList> directDLs = getAllDirectDLs(this, entry);
    HashSet<String> directDLSet = new HashSet<String>();
    HashSet<String> checked = new HashSet<String>();
    List<DistributionList> result = new ArrayList<DistributionList>();

    Stack<DistributionList> dlsToCheck = new Stack<DistributionList>();

    for (DistributionList dl : directDLs) {
        dlsToCheck.push(dl);/*from   ww w  . j  ava2 s.  co m*/
        directDLSet.add(dl.getName());
    }

    while (!dlsToCheck.isEmpty()) {
        DistributionList dl = dlsToCheck.pop();
        if (checked.contains(dl.getId()))
            continue;
        result.add(dl);
        checked.add(dl.getId());
        if (directOnly)
            continue;

        List<DistributionList> newLists = getAllDirectDLs(this, dl);

        for (DistributionList newDl : newLists) {
            if (!directDLSet.contains(newDl.getName())) {
                if (via != null) {
                    via.put(newDl.getName(), dl.getName());
                }
                dlsToCheck.push(newDl);
            }
        }
    }
    Collections.sort(result);
    return result;
}

From source file:org.fornax.cartridges.sculptor.smartclient.server.ScServlet.java

private String mapObjToOutput(Object obj, int maxDepth, Stack<Object> serStack, boolean useGwtArray,
        boolean translateValue) {
    if (serStack.size() == 0) {
        log.log(Level.FINER, "Serializing START {0}", obj);
    }/*ww w. j a v  a  2  s. c  om*/

    // Avoid recursion
    if (serStack.size() == maxDepth && !(obj instanceof Date || obj instanceof Number || obj instanceof Boolean
            || obj instanceof CharSequence || obj instanceof Enum)) {
        String objId = getIdFromObj(obj);
        return objId == null ? Q + Q : objId;
    }
    if (serStack.contains(obj)) {
        return getIdFromObj(obj);
        // return Q+"ref: "+obj.getClass().getName()+"@"+obj.hashCode()+Q;
    }
    serStack.push(obj);

    String startArray = useGwtArray ? "$wnd.Array.create([" : "[";
    String endArray = useGwtArray ? "])" : "]";

    StringBuilder recordData = new StringBuilder();
    if (obj == null) {
        recordData.append("null");
    } else if (obj instanceof Map) {
        recordData.append("{");
        Map objMap = (Map) obj;
        String delim = "";
        for (Object objKey : objMap.keySet()) {
            recordData.append(delim).append(objKey).append(":")
                    .append(mapObjToOutput(objMap.get(objKey), maxDepth, serStack, useGwtArray, false));
            delim = " , ";
        }
        recordData.append("}");
    } else if (obj instanceof Collection) {
        recordData.append(startArray);
        Collection objSet = (Collection) obj;
        String delim = "";
        for (Object objVal : objSet) {
            recordData.append(delim).append(mapObjToOutput(objVal, maxDepth, serStack, useGwtArray, false));
            delim = " , ";
        }
        recordData.append(endArray);
    } else if (obj instanceof List) {
        recordData.append(startArray);
        List objList = (List) obj;
        String delim = "";
        for (Object objVal : objList) {
            recordData.append(delim).append(mapObjToOutput(objVal, maxDepth, serStack, useGwtArray, false));
            delim = " , ";
        }
        recordData.append(endArray);
    } else if (obj instanceof Object[]) {
        recordData.append(startArray);
        Object[] objArr = (Object[]) obj;
        String delim = "";
        for (Object objVal : objArr) {
            recordData.append(delim).append(mapObjToOutput(objVal, maxDepth, serStack, useGwtArray, false));
            delim = " , ";
        }
        recordData.append(endArray);
    } else if (obj instanceof Date) {
        Date objDate = (Date) obj;
        // recordData.append(Q+dateTimeFormat.format(objDate)+Q);
        recordData.append("new Date(" + objDate.getTime() + ")");
    } else if (obj instanceof Boolean) {
        recordData.append(obj);
    } else if (obj instanceof Number) {
        recordData.append(obj);
    } else if (obj instanceof CharSequence) {
        String strObj = obj.toString();
        if (strObj.startsWith(Main.JAVASCRIPT_PREFIX) && useGwtArray) {
            recordData.append(" ").append(strObj.substring(Main.JAVASCRIPT_PREFIX.length()));
        } else if (strObj.startsWith("function") && useGwtArray) {
            recordData.append(" ").append(strObj);
        } else {
            strObj = translateValue ? translate(strObj) : strObj;
            String escapeString = strObj.replaceAll("\\\\", "\\\\\\\\").replaceAll("\"", "\\\\\"")
                    .replaceAll("\\r", "\\\\r").replaceAll("\\n", "\\\\n");
            recordData.append(Q + escapeString + Q);
        }
    } else if (obj instanceof Enum) {
        String val = ((Enum) obj).name();
        if (useGwtArray) {
            try {
                Method getValMethod = obj.getClass().getMethod("getValue", (Class[]) null);
                val = (String) getValMethod.invoke(obj, (Object[]) null);
            } catch (Exception e) {
                // no method getValue
            }
        }
        recordData.append(Q + val + Q);
    } else {
        String className = obj.getClass().getName();
        ServiceDescription serviceForClass = findServiceByClassName(className);
        log.log(Level.FINER, "Serializing class {0}", className);
        if (serStack.size() > 2 && serviceForClass != null) {
            recordData.append(getIdFromObj(obj));
        } else {
            // Use reflection
            recordData.append("{");
            String delim = "";
            String jsonPostfix = null;
            Method[] methods = obj.getClass().getMethods();
            for (Method m : methods) {
                boolean translateThisValue = false;
                String mName;
                if (m.getName().startsWith(GET_TRANSLATE)) {
                    translateThisValue = true;
                    mName = m.getName().substring(GET_TRANSLATE_LENGTH);
                } else if (m.getName().startsWith("is")) {
                    mName = m.getName().substring(2);
                } else {
                    mName = m.getName().substring(3);
                }

                if (mName.length() > 1 && Character.isLowerCase(mName.charAt(1))) {
                    mName = mName.substring(0, 1).toLowerCase() + mName.substring(1);
                }

                if (m.getName().startsWith("getJsonPostfix") && m.getParameterTypes().length == 0
                        && String.class.equals(m.getReturnType())) {
                    try {
                        jsonPostfix = (String) m.invoke(obj, new Object[] {});
                    } catch (Throwable e) {
                        log.log(Level.FINE, "Mapping error", e);
                    }
                } else if (!m.getDeclaringClass().getName().startsWith("org.hibernate")
                        && m.getDeclaringClass() != Object.class && m.getDeclaringClass() != Class.class
                        && (m.getName().startsWith("get") || m.getName().startsWith("is"))
                        && m.getParameterTypes().length == 0 && m.getReturnType() != null
                        && !isHiddenField(m.getDeclaringClass().getName(), mName)) {
                    log.log(Level.FINEST, "Reflection invoking name={0} declaringClass={1} on {2}[{3}]",
                            new Object[] { m.getName(), m.getDeclaringClass(), obj, obj.getClass() });
                    try {
                        Object result = m.invoke(obj, new Object[] {});
                        if (result != null) {
                            mName = mName.startsWith("xxx") ? mName.substring(3) : mName;
                            String resultClassName = AopUtils.getTargetClass(result).getName();
                            String idVal = getIdFromObj(result);
                            String valStr;
                            if (findServiceByClassName(resultClassName) != null && idVal != null) {
                                recordData.append(delim).append(mName).append(":").append(idVal);
                                String refField = ds2Ref.get(resultClassName);
                                if (refField != null) {
                                    Object realVal = getValFromObj(refField, result);
                                    valStr = realVal == null ? Q + Q : Q + realVal + Q;
                                } else {
                                    valStr = Q + "UNKNOWN" + Q;
                                }
                                mName = mName + "_VAL";
                                delim = ", ";
                            } else {
                                valStr = mapObjToOutput(result, maxDepth, serStack, useGwtArray,
                                        translateThisValue);
                            }
                            recordData.append(delim).append(mName).append(":").append(valStr);
                            delim = ", ";
                        }
                    } catch (Throwable e) {
                        log.log(Level.FINE, "Mapping error", e);
                    }
                }
            }

            if (jsonPostfix != null) {
                recordData.append(delim).append(jsonPostfix).append("}");
            } else {
                recordData.append("}");
            }
        }
    }
    serStack.pop();
    return recordData.toString();
}

From source file:edu.ku.brc.specify.ui.db.ResultSetTableModel.java

@Override
//@SuppressWarnings("null")
public synchronized void exectionDone(final SQLExecutionProcessor process, final ResultSet resultSet) {
    if (statusBar != null) {
        statusBar.incrementValue(getClass().getSimpleName());
    }/*  w w  w .j  a va  2  s  .c o  m*/

    if (resultSet == null || results == null) {
        log.error("The " + (resultSet == null ? "resultSet" : "results") + " is null.");
        if (propertyListener != null) {
            propertyListener.propertyChange(new PropertyChangeEvent(this, "rowCount", null, 0));
        }
        return;
    }

    List<ERTICaptionInfo> captions = results.getVisibleCaptionInfo();

    // This can do one of two things:
    // 1) Take multiple columns and create an object and use a DataObjectFormatter to format the object.
    // 2) Table multiple objects that were derived from the columns and roll those up into a single column's value.
    //    This happens when you get back rows of info where part of the columns are duplicated because you really
    //    want those value to be put into a single column.
    //
    // Step One - Is to figure out what type of object needs to be created and what the Columns are 
    //            that need to be set into the object so the dataObjFormatter can do its job.
    //
    // Step Two - If the objects are being aggregated then the object created from the columns are added to a List
    //            and then last formatted as an "aggregation"

    try {
        if (resultSet.next()) {
            ResultSetMetaData metaData = resultSet.getMetaData();

            // Composite
            boolean hasCompositeObj = false;
            DataObjSwitchFormatter dataObjFormatter = null;
            UIFieldFormatterIFace formatter = null;
            Object compObj = null;

            // Aggregates
            ERTICaptionInfo aggCaption = null;
            ERTICaptionInfo compositeCaption = null;
            Vector<Object> aggList = null;
            DataObjectSettable aggSetter = null;
            Stack<Object> aggListRecycler = null;

            DataObjectSettable dataSetter = null; // data getter for Aggregate or the Subclass

            // Loop through the caption to figure out what columns will be displayed.
            // Watch for Captions with an Aggregator or Composite 
            numColumns = captions.size();
            for (ERTICaptionInfo caption : captions) {
                colNames.addElement(caption.getColLabel());

                int inx = caption.getPosIndex() + 1;
                //log.debug(metaData.getColumnClassName(inx));
                Class<?> cls = null;
                try {
                    cls = Class.forName(metaData.getColumnClassName(inx));
                    if (cls == Calendar.class || cls == java.sql.Date.class || cls == Date.class) {
                        cls = String.class;
                    }
                } catch (SQLException ex) {
                    cls = String.class;
                }
                classNames.addElement(cls);
                caption.setColClass(cls);

                if (caption.getAggregatorName() != null) {
                    //log.debug("The Agg is ["+caption.getAggregatorName()+"] "+caption.getColName());

                    // Alright we have an aggregator
                    aggList = new Vector<Object>();
                    aggListRecycler = new Stack<Object>();
                    aggCaption = caption;
                    aggSetter = DataObjectSettableFactory.get(aggCaption.getAggClass().getName(),
                            FormHelper.DATA_OBJ_SETTER);

                    // Now check to see if we are aggregating the this type of object or a child object of this object
                    // For example Collectors use an Agent as part of the aggregation
                    if (aggCaption.getSubClass() != null) {
                        dataSetter = DataObjectSettableFactory.get(aggCaption.getSubClass().getName(),
                                FormHelper.DATA_OBJ_SETTER);
                    } else {
                        dataSetter = aggSetter;
                    }

                } else if (caption.getColInfoList() != null) {
                    formatter = caption.getUiFieldFormatter();
                    if (formatter != null) {
                        compositeCaption = caption;
                    } else {
                        // OK, now aggregation but we will be rolling up multiple columns into a single object for formatting
                        // We need to get the formatter to see what the Class is of the object
                        hasCompositeObj = true;
                        aggCaption = caption;
                        dataObjFormatter = caption.getDataObjFormatter();
                        if (dataObjFormatter != null) {
                            if (dataObjFormatter.getDataClass() != null) {
                                aggSetter = DataObjectSettableFactory.get(
                                        dataObjFormatter.getDataClass().getName(),
                                        "edu.ku.brc.af.ui.forms.DataSetterForObj");
                            } else {
                                log.error("formatterObj.getDataClass() was null for " + caption.getColName());
                            }
                        } else {
                            log.error("DataObjFormatter was null for " + caption.getColName());
                        }
                    }

                }
                //colNames.addElement(metaData.getColumnName(i));
                //System.out.println("**************** " + caption.getColLabel()+ " "+inx+ " " + caption.getColClass().getSimpleName());
            }

            // aggCaption will be non-null for both a Aggregate AND a Composite
            if (aggCaption != null) {
                // Here we need to dynamically discover what the column indexes are that we to grab
                // in order to set them into the created data object
                for (ERTICaptionInfo.ColInfo colInfo : aggCaption.getColInfoList()) {
                    for (int i = 0; i < metaData.getColumnCount(); i++) {
                        String colName = StringUtils.substringAfterLast(colInfo.getColumnName(), ".");
                        if (colName.equalsIgnoreCase(metaData.getColumnName(i + 1))) {
                            colInfo.setPosition(i);
                            break;
                        }
                    }
                }

                // Now check to see if there is an Order Column because the Aggregator 
                // might need it for sorting the Aggregation
                String ordColName = aggCaption.getOrderCol();
                if (StringUtils.isNotEmpty(ordColName)) {
                    String colName = StringUtils.substringAfterLast(ordColName, ".");
                    //log.debug("colName ["+colName+"]");
                    for (int i = 0; i < metaData.getColumnCount(); i++) {
                        //log.debug("["+colName+"]["+metaData.getColumnName(i+1)+"]");
                        if (colName.equalsIgnoreCase(metaData.getColumnName(i + 1))) {
                            aggCaption.setOrderColIndex(i);
                            break;
                        }
                    }
                    if (aggCaption.getOrderColIndex() == -1) {
                        log.error("Agg Order Column Index wasn't found [" + ordColName + "]");
                    }
                }
            }

            if (ids == null) {
                ids = new Vector<Integer>();
            } else {
                ids.clear();
            }

            // Here is the tricky part.
            // When we are doing a Composite we are just taking multiple columns and 
            // essentially replace them with a single value from the DataObjFormatter
            //
            // But when doing an Aggregation we taking several rows and rolling them up into a single value.
            // so this code knows when it is doing an aggregation, so it knows to only add a new row to the display-able
            // results when primary id changes.

            DataObjFieldFormatMgr dataObjMgr = DataObjFieldFormatMgr.getInstance();
            Vector<Object> row = null;
            boolean firstTime = true;
            int prevId = Integer.MAX_VALUE; // really can't assume any value but will choose Max

            int numCols = resultSet.getMetaData().getColumnCount();
            do {
                int id = resultSet.getInt(1);
                //log.debug("id: "+id+"  prevId: "+prevId);

                // Remember aggCaption is used by both a Aggregation and a Composite
                if (aggCaption != null && !hasCompositeObj) {
                    if (firstTime) {
                        prevId = id;
                        row = new Vector<Object>();
                        firstTime = false;
                        cache.add(row);
                        ids.add(id);

                    } else if (id != prevId) {
                        //log.debug("Agg List len: "+aggList.size());

                        if (row != null && aggList != null) {
                            int aggInx = captions.indexOf(aggCaption);
                            row.remove(aggInx);
                            row.insertElementAt(dataObjMgr.aggregate(aggList, aggCaption.getAggClass()),
                                    aggInx);

                            if (aggListRecycler != null) {
                                aggListRecycler.addAll(aggList);
                            }
                            aggList.clear();

                            row = new Vector<Object>();
                            cache.add(row);
                            ids.add(id);
                        }
                        prevId = id;

                    } else if (row == null) {
                        row = new Vector<Object>();
                        cache.add(row);
                        ids.add(id);
                    }
                } else {
                    row = new Vector<Object>();
                    cache.add(row);
                    ids.add(id);
                }

                // Now for each Caption column get a value
                for (ERTICaptionInfo caption : captions) {
                    int posIndex = caption.getPosIndex();
                    if (caption == aggCaption) // Checks to see if we need to take multiple columns and make one column
                    {
                        if (hasCompositeObj) // just doing a Composite
                        {
                            if (aggSetter != null && row != null && dataObjFormatter != null) {
                                if (compObj == null) {
                                    compObj = aggCaption.getAggClass().newInstance();
                                }

                                for (ERTICaptionInfo.ColInfo colInfo : aggCaption.getColInfoList()) {
                                    setField(aggSetter, compObj, colInfo.getFieldName(),
                                            colInfo.getFieldClass(), resultSet, colInfo.getPosition());
                                }
                                row.add(DataObjFieldFormatMgr.getInstance().format(compObj,
                                        compObj.getClass()));

                            } else if (formatter != null) {
                                int len = compositeCaption.getColInfoList().size();
                                Object[] val = new Object[len];
                                int i = 0;
                                for (ERTICaptionInfo.ColInfo colInfo : compositeCaption.getColInfoList()) {
                                    int colInx = colInfo.getPosition() + posIndex + 1;
                                    if (colInx < numCols) {
                                        val[i++] = resultSet.getObject(colInx);
                                    } else {
                                        //val[i++] = resultSet.getObject(posIndex+1);
                                        val[i++] = "(Missing Data)";
                                    }
                                }
                                row.add(formatter.formatToUI(val));

                            } else {
                                log.error("Aggregator is null! [" + aggCaption.getAggregatorName()
                                        + "] or row or aggList");
                            }
                        } else if (aggSetter != null && row != null && aggList != null) // Doing an Aggregation
                        {
                            Object aggObj;
                            if (aggListRecycler.size() == 0) {
                                aggObj = aggCaption.getAggClass().newInstance();
                            } else {
                                aggObj = aggListRecycler.pop();
                            }
                            Object aggSubObj = aggCaption.getSubClass() != null
                                    ? aggCaption.getSubClass().newInstance()
                                    : null;
                            aggList.add(aggObj);

                            //@SuppressWarnings("unused")
                            //DataObjAggregator aggregator = DataObjFieldFormatMgr.getInstance().getAggregator(aggCaption.getAggregatorName());
                            //log.debug(" aggCaption.getOrderColIndex() "+ aggCaption.getOrderColIndex());

                            //aggSetter.setFieldValue(aggObj, aggregator.getOrderFieldName(), resultSet.getObject(aggCaption.getOrderColIndex() + 1));

                            Object dataObj;
                            if (aggSubObj != null) {
                                aggSetter.setFieldValue(aggObj, aggCaption.getSubClassFieldName(), aggSubObj);
                                dataObj = aggSubObj;
                            } else {
                                dataObj = aggObj;
                            }

                            for (ERTICaptionInfo.ColInfo colInfo : aggCaption.getColInfoList()) {
                                setField(dataSetter, dataObj, colInfo.getFieldName(), colInfo.getFieldClass(),
                                        resultSet, colInfo.getPosition());
                            }
                            row.add("PlaceHolder");

                        } else if (aggSetter == null || aggList == null) {
                            log.error("Aggregator is null! [" + aggCaption.getAggregatorName() + "] or aggList["
                                    + aggList + "]");
                        }

                    } else if (row != null) {
                        if (caption.getColName() == null && caption.getColInfoList().size() > 0) {
                            int len = caption.getColInfoList().size();
                            Object[] val = new Object[len];
                            for (int i = 0; i < caption.getColInfoList().size(); i++) {
                                int inx = posIndex + 1 + i;
                                val[i] = caption.processValue(resultSet.getObject(inx));
                            }
                            row.add(caption.getUiFieldFormatter().formatToUI(val));
                            //col += caption.getColInfoList().size() - 1;

                        } else {
                            Object obj = caption.processValue(resultSet.getObject(posIndex + 1));
                            row.add(obj);
                        }
                    }
                }

            } while (resultSet.next());

            // We were always setting the rolled up data when the ID changed
            // but on the last row we need to do it here manually (so to speak)
            if (aggCaption != null && aggList != null && aggList.size() > 0 && row != null) {
                int aggInx = captions.indexOf(aggCaption);
                row.remove(aggInx);
                String colStr;
                if (StringUtils.isNotEmpty(aggCaption.getAggregatorName())) {
                    colStr = DataObjFieldFormatMgr.getInstance().aggregate(aggList,
                            aggCaption.getAggregatorName());

                } else {
                    colStr = DataObjFieldFormatMgr.getInstance().aggregate(aggList, aggCaption.getAggClass());
                }
                row.insertElementAt(colStr, aggInx);
                aggList.clear();
                aggListRecycler.clear();
            }

            fireTableStructureChanged();
            fireTableDataChanged();
        }

    } catch (Exception ex) {
        ex.printStackTrace();
    }

    if (propertyListener != null) {
        propertyListener
                .propertyChange(new PropertyChangeEvent(this, "rowCount", null, new Integer(cache.size())));
    }
}

From source file:com.aurel.track.exchange.excel.ExcelImportBL.java

/**
 * Get the workItems list and validate if all the fields of the excel sheet
 * are correct//from  w ww.  j a  va  2  s.c  o m
 * 
 * @param workbook
 * @param selectedSheet
 * @param personID
 * @param locale
 * @param columnIndexToFieldIDMap
 * @param fieldIDToColumnIndexMap
 * @param lastSavedIdentifierFieldIDIsSet
 * @param defaultValuesMap
 * @param invalidValueHandlingMap
 * @param gridErrorsMap
 * @param rowErrorsMap
 * @return
 */
static SortedMap<Integer, TWorkItemBean> getAndValidateGridData(Workbook workbook, Integer selectedSheet,
        Integer personID, Locale locale, Map<Integer, Integer> columnIndexToFieldIDMap,
        Map<Integer, Integer> fieldIDToColumnIndexMap, Set<Integer> lastSavedIdentifierFieldIDIsSet,
        Map<Integer, Integer> defaultValuesMap, Map<Integer, Integer> invalidValueHandlingMap,
        Map<Integer, Map<Integer, List<Integer>>> rowNoToPseudoFieldsOriginal,
        Map<Integer, Map<Integer, List<Integer>>> rowNoToPseudoFieldsExcel,
        Map<Integer, SortedMap<Integer, SortedMap<String, ErrorData>>> gridErrorsMap,
        Map<Integer, SortedSet<Integer>> rowErrorsMap, Map<Integer, SortedSet<Integer>> requiredFieldErrorsMap,
        Map<Integer, Integer> rowToParentRow) {
    SortedMap<Integer, TWorkItemBean> workItemBeansMap = new TreeMap<Integer, TWorkItemBean>();
    Sheet sheet = workbook.getSheetAt(selectedSheet.intValue());
    // get the column indexes for project and issueType
    Integer projectColumn = fieldIDToColumnIndexMap.get(SystemFields.INTEGER_PROJECT);
    Integer issueTypeColumn = fieldIDToColumnIndexMap.get(SystemFields.INTEGER_ISSUETYPE);
    // Maps to spare additional database accesses for default values
    Map<Integer, String> defaultShowValuesMap = new HashMap<Integer, String>();
    Map<Integer, String> defaultLocalizedFieldLabels = new HashMap<Integer, String>();
    Integer originalProject = null;
    Integer originalIssueType = null;
    Set<Integer> mandatoryIdentifierFields = ExcelFieldMatchBL.getMandatoryIdentifierFields();
    Map<Integer, Map<String, ILabelBean>> systemLookups = loadBaseLookups(personID, locale);
    Map<String, ILabelBean> projectLookups = systemLookups.get(SystemFields.INTEGER_PROJECT);
    Map<Integer, Map<Integer, Map<String, ILabelBean>>> projectSpecificLookups = null;
    if (projectLookups != null) {
        projectSpecificLookups = loadProjectLookups(GeneralUtils
                .createIntegerListFromBeanList(GeneralUtils.createListFromCollection(projectLookups.values())));
    }
    boolean projectSpecificIDsActive = ApplicationBean.getInstance().getSiteBean().getProjectSpecificIDsOn();
    Map<Integer, TProjectBean> projectBeansMap = new HashMap<Integer, TProjectBean>();
    if (projectSpecificIDsActive) {
        List<TProjectBean> projectBeans = ProjectBL.loadUsedProjectsFlat(personID);
        if (projectBeans != null) {
            for (TProjectBean projectBean : projectBeans) {
                Integer projectID = projectBean.getObjectID();
                projectBeansMap.put(projectID, projectBean);
                String label = projectBean.getLabel();
                String projectPrefix = projectBean.getPrefix();
                if (projectPrefix == null || "".equals(projectPrefix)) {
                    LOGGER.info("The project " + label + " with ID " + projectID
                            + " has no prefix, consquently project specific item numbers might not be recognized");
                }
            }
        }
    }
    /**
     * Process the rows only to gather the projects to issueTypes to get the
     * roles and restrictions once for all issues
     */
    Map<Integer, Set<Integer>> projectToIssueTypesMap = new HashMap<Integer, Set<Integer>>();
    for (Row row : sheet) {
        int rowNum = row.getRowNum();
        if (rowNum == 0) {
            // only the data rows are processed (the header row is not
            // important now)
            continue;
        }
        SerializableBeanAllowedContext serializableBeanAllowedContext = new SerializableBeanAllowedContext();
        serializableBeanAllowedContext.setPersonID(personID);
        serializableBeanAllowedContext.setNew(true);
        // get the project and issueType first because the other fields
        // could depend on these issueTypes
        // process the project column
        Integer projectID = null;
        if (projectColumn != null) {
            try {
                projectID = (Integer) getAttributeValue(row.getCell(projectColumn),
                        SystemFields.INTEGER_PROJECT, null, serializableBeanAllowedContext, locale,
                        invalidValueHandlingMap, systemLookups, projectSpecificLookups);
            } catch (Exception e) {
            }
        }
        if (projectID == null) {
            // no project column exists on the sheet: take the default value
            // which is
            // surely specified, otherwise it would fail at
            // validateRequiredColumns()
            projectID = defaultValuesMap.get(SystemFields.INTEGER_PROJECT);
        }
        if (projectID != null) {
            serializableBeanAllowedContext.setProjectID(projectID);
        }
        // process the issueType column
        Integer issueTypeID = null;
        if (issueTypeColumn != null) {
            try {
                issueTypeID = (Integer) getAttributeValue(row.getCell(issueTypeColumn),
                        SystemFields.INTEGER_ISSUETYPE, null, serializableBeanAllowedContext, locale,
                        invalidValueHandlingMap, systemLookups, projectSpecificLookups);
            } catch (Exception e) {
            }
        }
        if (issueTypeID == null) {
            // no issue type column exists on the sheet: take the default
            // value which is
            // surely specified, otherwise it would fail at
            // validateRequiredColumns()
            issueTypeID = defaultValuesMap.get(SystemFields.INTEGER_ISSUETYPE);
        }
        if (projectID != null) {
            Set<Integer> issueTypes = projectToIssueTypesMap.get(projectID);
            if (issueTypes == null) {
                issueTypes = new HashSet<Integer>();
                projectToIssueTypesMap.put(projectID, issueTypes);
            }
            if (issueTypeID != null) {
                issueTypes.add(issueTypeID);
            }
        }
    }
    Map<Integer, Map<Integer, Map<Integer, TFieldConfigBean>>> projectsToIssueTypesToFieldConfigsMapForBottomUpFields = null;
    Map<Integer, Map<Integer, Map<String, Object>>> projectsIssueTypesFieldSettingsMapForBottomUpFields = null;
    Map<Integer, Map<Integer, Map<Integer, Integer>>> fieldRestrictions = AccessBeans
            .getFieldRestrictions(personID, projectToIssueTypesMap, null, true);
    Set<Integer> possibleBottomUpFields = FieldRuntimeBL.getPossibleBottomUpFields();
    for (Iterator<Integer> iterator = possibleBottomUpFields.iterator(); iterator.hasNext();) {
        if (!fieldIDToColumnIndexMap.containsKey(iterator.next())) {
            // remove possible bottom up field if not mapped
            iterator.remove();
        }
        if (!possibleBottomUpFields.isEmpty()) {
            // at least one bottom up date was mapped
            projectsToIssueTypesToFieldConfigsMapForBottomUpFields = FieldRuntimeBL
                    .loadFieldConfigsInContextsAndTargetProjectAndIssueType(projectToIssueTypesMap,
                            possibleBottomUpFields, locale, null, null);
            projectsIssueTypesFieldSettingsMapForBottomUpFields = FieldRuntimeBL
                    .getFieldSettingsForFieldConfigs(projectsToIssueTypesToFieldConfigsMapForBottomUpFields);
        }
    }

    /**
     * now process the rows in detail one by one
     */
    Stack<Integer> parentStack = new Stack<Integer>();
    Map<Integer, Integer> rowToIndent = new HashMap<Integer, Integer>();
    for (Row row : sheet) {
        int rowNum = row.getRowNum();
        if (rowNum == 0) {
            // only the data rows are processed (the header row is not
            // important now)
            continue;
        }
        boolean excelValueFound = false;
        // whether the project column is mapped and excel value if found for
        // project
        boolean mappedProject = false;
        SerializableBeanAllowedContext serializableBeanAllowedContext = new SerializableBeanAllowedContext();
        serializableBeanAllowedContext.setPersonID(personID);
        serializableBeanAllowedContext.setNew(true);
        // get the project and issueType first because the other fields
        // could depend on these issueTypes
        // process the project column
        Integer projectID = null;
        if (projectColumn != null) {
            try {
                projectID = (Integer) getAttributeValue(row.getCell(projectColumn),
                        SystemFields.INTEGER_PROJECT, null, serializableBeanAllowedContext, locale,
                        invalidValueHandlingMap, systemLookups, projectSpecificLookups);
                if (projectID != null) {
                    mappedProject = true;
                    excelValueFound = true;
                }
            } catch (ExcelImportNotExistingCellValueException e) {
                addGridError(gridErrorsMap, NOT_EXISTING_ERRORS, rowNum,
                        ExcelFieldMatchBL.colNumericToLetter(projectColumn), SystemFields.INTEGER_PROJECT,
                        e.getMessage());
            } catch (ExcelImportNotAllowedCellValueException e) {
                addGridError(gridErrorsMap, NOT_ALLOWED_ERRORS, rowNum,
                        ExcelFieldMatchBL.colNumericToLetter(projectColumn), SystemFields.INTEGER_PROJECT,
                        e.getMessage());
            } catch (ExcelImportInvalidCellValueException e) {
                addGridError(gridErrorsMap, INVALID_ERRORS, rowNum,
                        ExcelFieldMatchBL.colNumericToLetter(projectColumn), SystemFields.INTEGER_PROJECT,
                        e.getMessage());
            }
        }
        if (projectID == null) {
            // no project column exists on the sheet: take the default value
            // which is
            // surely specified, otherwise it would fail at
            // validateRequiredColumns()
            projectID = defaultValuesMap.get(SystemFields.INTEGER_PROJECT);
        }
        if (projectID != null) {
            serializableBeanAllowedContext.setProjectID(projectID);
        }
        // process the issueType column
        Integer issueTypeID = null;
        if (issueTypeColumn != null) {
            try {
                issueTypeID = (Integer) getAttributeValue(row.getCell(issueTypeColumn),
                        SystemFields.INTEGER_ISSUETYPE, null, serializableBeanAllowedContext, locale,
                        invalidValueHandlingMap, systemLookups, projectSpecificLookups);
                if (issueTypeID != null) {
                    excelValueFound = true;
                }
            } catch (ExcelImportNotExistingCellValueException e) {
                addGridError(gridErrorsMap, NOT_EXISTING_ERRORS, rowNum,
                        ExcelFieldMatchBL.colNumericToLetter(issueTypeColumn), SystemFields.INTEGER_ISSUETYPE,
                        e.getMessage());
            } catch (ExcelImportNotAllowedCellValueException e) {
                addGridError(gridErrorsMap, NOT_ALLOWED_ERRORS, rowNum,
                        ExcelFieldMatchBL.colNumericToLetter(issueTypeColumn), SystemFields.INTEGER_ISSUETYPE,
                        e.getMessage());
            } catch (ExcelImportInvalidCellValueException e) {
                addGridError(gridErrorsMap, INVALID_ERRORS, rowNum,
                        ExcelFieldMatchBL.colNumericToLetter(issueTypeColumn), SystemFields.INTEGER_ISSUETYPE,
                        e.getMessage());
            }
        }
        if (issueTypeID == null) {
            // no issue type column exists on the sheet: take the default
            // value which is
            // surely specified, otherwise it would fail at
            // validateRequiredColumns()
            issueTypeID = defaultValuesMap.get(SystemFields.INTEGER_ISSUETYPE);
        }
        if (issueTypeID != null) {
            serializableBeanAllowedContext.setIssueTypeID(issueTypeID);
        }
        /*
         * gather the values for the identifier fields and try to get an
         * existing workItem by these fields
         */
        Map<Integer, Object> identifierFieldValues = new HashMap<Integer, Object>();
        if (lastSavedIdentifierFieldIDIsSet != null && !lastSavedIdentifierFieldIDIsSet.isEmpty()) {
            for (Integer fieldID : lastSavedIdentifierFieldIDIsSet) {
                Integer attributeFieldID = fieldID;
                if (SystemFields.INTEGER_ISSUENO.equals(fieldID) && projectSpecificIDsActive) {
                    attributeFieldID = SystemFields.INTEGER_PROJECT_SPECIFIC_ISSUENO;
                }
                Object attributeValue = null;
                Integer columnIndex = null;
                try {
                    columnIndex = fieldIDToColumnIndexMap.get(fieldID);
                    attributeValue = getAttributeValue(row.getCell(columnIndex), attributeFieldID, null,
                            serializableBeanAllowedContext, locale, invalidValueHandlingMap, systemLookups,
                            projectSpecificLookups);
                    if (attributeValue != null) {
                        identifierFieldValues.put(fieldID, attributeValue);
                        excelValueFound = true;
                    }
                } catch (ExcelImportNotExistingCellValueException e) {
                    if (!SystemFields.INTEGER_PROJECT.equals(fieldID)
                            && !SystemFields.INTEGER_ISSUETYPE.equals(fieldID)) {
                        // if project or issueType are set as identifier
                        // fields and
                        // have grid error they should be already collected
                        // in gridErrorsMap
                        addGridError(gridErrorsMap, NOT_EXISTING_ERRORS, rowNum,
                                ExcelFieldMatchBL.colNumericToLetter(columnIndex), fieldID, e.getMessage());
                    }
                } catch (ExcelImportNotAllowedCellValueException e) {
                    if (!SystemFields.INTEGER_PROJECT.equals(fieldID)
                            && !SystemFields.INTEGER_ISSUETYPE.equals(fieldID)) {
                        // if project or issueType are set as identifier
                        // fields and
                        // have grid error they should be already collected
                        // in gridErrorsMap
                        addGridError(gridErrorsMap, NOT_ALLOWED_ERRORS, rowNum,
                                ExcelFieldMatchBL.colNumericToLetter(columnIndex), fieldID, e.getMessage());
                    }
                } catch (ExcelImportInvalidCellValueException e) {
                    if (!SystemFields.INTEGER_PROJECT.equals(fieldID)
                            && !SystemFields.INTEGER_ISSUETYPE.equals(fieldID)) {
                        // if project or issueType are set as identifier
                        // fields and
                        // have grid error they should be already collected
                        // in gridErrorsMap
                        addGridError(gridErrorsMap, INVALID_ERRORS, rowNum,
                                ExcelFieldMatchBL.colNumericToLetter(columnIndex), fieldID, e.getMessage());
                    }
                }
            }
        }
        // always initialize the next workItem to null
        TWorkItemBean workItemBean = null;
        boolean itemIsNew = false;
        if (!identifierFieldValues.isEmpty()) {
            if (identifierFieldValues.get(SystemFields.INTEGER_ISSUENO) != null) {
                // is issueNo field mapped?
                if (projectSpecificIDsActive) {
                    // get by project specific itemID
                    String projectSpecificID = null;
                    try {
                        projectSpecificID = (String) identifierFieldValues.get(SystemFields.INTEGER_ISSUENO);
                    } catch (Exception e) {
                    }
                    if (projectSpecificID != null) {
                        // it should be trimmed because in excel the child
                        // issues are indented
                        workItemBean = ItemBL.loadWorkItemByProjectSpecificID(projectID, mappedProject,
                                projectBeansMap, projectSpecificID.trim());
                        if (workItemBean != null && LOGGER.isDebugEnabled()) {
                            LOGGER.debug("WorkItem " + projectSpecificID + " from row " + rowNum
                                    + " found by projectSpecificID");
                        }
                    }
                } else {
                    // get by "global" workItemID
                    Integer workItemID = null;
                    try {
                        workItemID = (Integer) identifierFieldValues.get(SystemFields.INTEGER_ISSUENO);
                    } catch (Exception e) {
                    }
                    if (workItemID != null) {
                        workItemBean = ItemBL.loadWorkItemSystemAttributes(workItemID);
                    }
                    if (workItemBean != null && LOGGER.isDebugEnabled()) {
                        LOGGER.debug("WorkItem " + workItemID + " from row " + rowNum + " found by workItemID");
                    }
                }
                if (workItemBean == null) {
                    // the issueNo field is set as identifier and the
                    // corresponding issue does't exist, report as error
                    addGridError(gridErrorsMap, WORKITEM_NOTEXIST_ERRORS, rowNum,
                            ExcelFieldMatchBL.colNumericToLetter(
                                    fieldIDToColumnIndexMap.get(SystemFields.INTEGER_ISSUENO)),
                            SystemFields.INTEGER_ISSUENO,
                            identifierFieldValues.get(SystemFields.INTEGER_ISSUENO).toString());
                    continue;
                }
            }
            if (workItemBean == null) {
                // workItem was not found by issueNo
                // (issueNo field was not mapped or issueNo value is missing
                // from excel or
                // the issue's project is not accessible if
                // projectSpecificIDsActive)
                // try with user defined identifier fields
                try {
                    workItemBean = ItemBL.loadWorkItemSystemAttributes(identifierFieldValues);
                } catch (ExcelImportNotUniqueIdentifiersException e) {
                    addRowError(rowErrorsMap, WORKITEM_MORE_THAN_ONE_EXIST, rowNum);
                    continue;
                }
                if (workItemBean != null && LOGGER.isDebugEnabled()) {
                    LOGGER.debug("WorkItem from row " + rowNum + " found by user defined identifier fields");
                }
            }
            if (workItemBean != null) {
                // existing workItem
                originalProject = workItemBean.getProjectID();
                originalIssueType = workItemBean.getListTypeID();
                // is it editable by the current person?
                if (!AccessBeans.isAllowedToChange(workItemBean, personID)) {
                    addRowError(rowErrorsMap, WORKITEM_NO_EDIT_RIGHT, rowNum);
                    continue;
                }
                // load also the custom attributes because when the workItem
                // will be updated
                // the custom attributes will also be compared to the
                // original value
                ItemBL.loadWorkItemCustomAttributes(workItemBean);
                serializableBeanAllowedContext.setWorkItemBeanOriginal(workItemBean);
                serializableBeanAllowedContext.setNew(false);
                // LOGGER.debug("WorkItem " + workItemBean.getObjectID() +
                // " from row " + rowNum + " found");
            }
        }
        boolean missingRequiredFound = false;
        if (workItemBean == null) {
            // not existing found by identifier fields, create a new one
            workItemBean = new TWorkItemBean();
            if (identifierFieldValues != null) {
                // preset the new workItem with the processed identifier
                // values
                for (Map.Entry<Integer, Object> identifierEntry : identifierFieldValues.entrySet()) {
                    workItemBean.setAttribute(identifierEntry.getKey(), identifierEntry.getValue());
                }
            }
            itemIsNew = true;
            LOGGER.debug("WorkItem from row " + rowNum + " not found. A new one will be created.");
        }
        if (projectID != null) {
            workItemBean.setAttribute(SystemFields.INTEGER_PROJECT, null, projectID);
        } else {
            if (itemIsNew) {
                // project column not mapped
                addRowError(requiredFieldErrorsMap, SystemFields.INTEGER_PROJECT, rowNum);
                missingRequiredFound = true;
            }
        }
        if (issueTypeID != null) {
            workItemBean.setAttribute(SystemFields.INTEGER_ISSUETYPE, null, issueTypeID);
        } else {
            if (itemIsNew) {
                // project column not mapped
                addRowError(requiredFieldErrorsMap, SystemFields.INTEGER_ISSUETYPE, rowNum);
                missingRequiredFound = true;
            }
        }
        if (missingRequiredFound) {
            continue;
        }
        Map<Integer, Integer> restrictedFields = null;
        projectID = workItemBean.getProjectID();
        issueTypeID = workItemBean.getListTypeID();
        if (projectID != null && issueTypeID != null) {
            Map<Integer, Map<Integer, Integer>> issueTypeRestrictions = fieldRestrictions.get(projectID);
            if (issueTypeRestrictions != null) {
                restrictedFields = issueTypeRestrictions.get(issueTypeID);
            }
            if (restrictedFields == null) {
                // no project or issue type mapped get the restriction now
                restrictedFields = AccessBeans.getFieldRestrictions(personID, projectID, issueTypeID, true);
                issueTypeRestrictions = new HashMap<Integer, Map<Integer, Integer>>();
                issueTypeRestrictions.put(issueTypeID, restrictedFields);
                fieldRestrictions.put(projectID, issueTypeRestrictions);
            }
            // new values exist
            if (originalProject != null && originalIssueType != null) {
                // workItem existed
                if (!projectID.equals(originalProject) || !issueTypeID.equals(originalIssueType)) {
                    if (!AccessBeans.isAllowedToChange(workItemBean, personID)) {
                        // move not allowed
                        addRowError(rowErrorsMap, WORKITEM_NO_EDIT_RIGHT, rowNum);
                        continue;
                    }
                }
            } else {
                // new workItem
                if (!AccessBeans.isAllowedToCreate(personID, projectID, issueTypeID)) {
                    // create not allowed
                    addRowError(rowErrorsMap, WORKITEM_NO_CREATE_RIGHT, rowNum);
                    continue;
                }
            }
        }
        // process the remaining cells
        Map<Integer, Integer> rowNoToIndentLevel = new HashMap<Integer, Integer>();
        for (Cell cell : row) {
            boolean attributeChanged = false;
            int columnIndex = cell.getColumnIndex();
            Integer fieldID = columnIndexToFieldIDMap.get(columnIndex);
            Integer fieldForRestriction = fieldID;
            if (fieldID == null) {
                // LOGGER.debug("No mapping found for column " +
                // columnIndex);
                continue;
            }
            if (fieldID.equals(SystemFields.INTEGER_PROJECT) || fieldID.equals(SystemFields.INTEGER_ISSUETYPE)
                    || identifierFieldValues.containsKey(fieldID)
                    || mandatoryIdentifierFields.contains(fieldID)) {
                // these values are already read
                continue;
            }
            if (fieldID.intValue() < 0) {
                // pseudo field: now only watchers
                if (fieldID.intValue() == TReportLayoutBean.PSEUDO_COLUMNS.INFORMANT_LIST
                        || fieldID.intValue() == TReportLayoutBean.PSEUDO_COLUMNS.CONSULTANT_LIST) {
                    fieldForRestriction = FieldsRestrictionsToRoleBL.PSEUDO_COLUMNS.WATCHERS;
                    String watcherValue = getStringCellValue(cell);
                    if (watcherValue == null || "".equals(watcherValue.trim())) {
                        continue;
                    }
                    Map<Integer, List<Integer>> watcherMapOriginal = rowNoToPseudoFieldsOriginal.get(rowNum);
                    if (watcherMapOriginal == null) {
                        watcherMapOriginal = new HashMap<Integer, List<Integer>>();
                        rowNoToPseudoFieldsOriginal.put(rowNum, watcherMapOriginal);
                    }
                    List<Integer> watcherListOriginal = null;
                    TWorkItemBean workItemBeanOriginal = serializableBeanAllowedContext
                            .getWorkItemBeanOriginal();
                    if (workItemBeanOriginal != null) {
                        if (fieldID.intValue() == TReportLayoutBean.PSEUDO_COLUMNS.INFORMANT_LIST) {
                            watcherListOriginal = GeneralUtils.createIntegerListFromBeanList(
                                    PersonBL.getDirectInformants(workItemBeanOriginal.getObjectID()));
                        } else {
                            watcherListOriginal = GeneralUtils.createIntegerListFromBeanList(
                                    PersonBL.getDirectConsultants(workItemBeanOriginal.getObjectID()));
                        }
                        watcherMapOriginal.put(fieldID, watcherListOriginal);
                    }
                    List<Integer> watcherListExcel = new LinkedList<Integer>();
                    String[] watcherNames = watcherValue
                            .split("\\" + ConsultedInformedLoaderBL.WATCHER_SPLITTER_VALUES_STRING);
                    if (watcherNames != null) {
                        Map<Integer, List<Integer>> watcherMapExcel = rowNoToPseudoFieldsExcel.get(rowNum);
                        if (watcherMapExcel == null) {
                            watcherMapExcel = new HashMap<Integer, List<Integer>>();
                            rowNoToPseudoFieldsExcel.put(rowNum, watcherMapExcel);
                        }
                        watcherMapExcel.put(fieldID, watcherListExcel);
                        for (int i = 0; i < watcherNames.length; i++) {
                            String watcherName = watcherNames[i];
                            Integer objectID = null;
                            try {
                                objectID = getWatcherValue(watcherName, fieldID, systemLookups,
                                        watcherListOriginal, serializableBeanAllowedContext, locale);
                            } catch (ExcelImportNotExistingCellValueException e) {
                                addGridError(gridErrorsMap, NOT_EXISTING_ERRORS, rowNum,
                                        ExcelFieldMatchBL.colNumericToLetter(columnIndex), fieldID,
                                        e.getMessage());
                            } catch (ExcelImportNotAllowedCellValueException e) {
                                addGridError(gridErrorsMap, NOT_ALLOWED_ERRORS, rowNum,
                                        ExcelFieldMatchBL.colNumericToLetter(columnIndex), fieldID,
                                        e.getMessage());
                            }
                            if (objectID != null) {
                                watcherListExcel.add(objectID);
                                excelValueFound = true;
                            }
                        }
                    }
                    attributeChanged = ConsInfBL.watcherChanged(watcherListOriginal, watcherListExcel);
                } else {
                    if (fieldID.intValue() == ExcelFieldMatchBL.LOCAL_PARENT_PSEUDO_COLUMN) {
                        // local parent - child hierarchy (for new items)
                        Integer pseudoHierarchyColumn = fieldIDToColumnIndexMap
                                .get(ExcelFieldMatchBL.LOCAL_PARENT_PSEUDO_COLUMN);
                        if (pseudoHierarchyColumn != null) {
                            String hierarchyColumn = getStringCellValue(row.getCell(pseudoHierarchyColumn));
                            if (hierarchyColumn != null && hierarchyColumn.length() > 0) {
                                int previousIndent = 0;
                                if (!parentStack.isEmpty()) {
                                    Integer previousRow = parentStack.peek();
                                    if (rowToIndent.get(previousRow) != null) {
                                        previousIndent = rowToIndent.get(previousRow).intValue();
                                    }
                                }
                                int actualIndent = hierarchyColumn.length();
                                rowToIndent.put(rowNum, actualIndent);
                                rowNoToIndentLevel.put(rowNum, actualIndent);
                                if (previousIndent == actualIndent) {
                                    // sibling: same parent as the sibling's
                                    // parent
                                    if (!parentStack.isEmpty()) {
                                        // remove the sibling from stack
                                        parentStack.pop();
                                        if (!parentStack.isEmpty()) {
                                            // if the stack is still not
                                            // empty then the peek is teh
                                            // parent
                                            Integer parentRow = parentStack.peek();
                                            rowToParentRow.put(rowNum, parentRow);
                                        }
                                    }
                                } else {
                                    if (actualIndent > previousIndent) {
                                        // child of the previous row
                                        if (actualIndent - previousIndent > 1) {
                                            // jump more than one in deep is
                                            // error
                                            addGridError(gridErrorsMap, INCONSISTENT_HIERARCHY_ERRORS, rowNum,
                                                    ExcelFieldMatchBL.colNumericToLetter(columnIndex), fieldID,
                                                    hierarchyColumn);
                                        }
                                        if (!parentStack.isEmpty()) {
                                            // add previous row as parent
                                            Integer parentRow = parentStack.peek();
                                            rowToParentRow.put(rowNum, parentRow);
                                        }
                                    } else {
                                        // new hierarchy: nothing to do with
                                        // the previous row
                                        int difference = previousIndent - actualIndent;
                                        for (int i = 0; i <= difference; i++) {
                                            // pop to find the parent
                                            if (!parentStack.isEmpty()) {
                                                parentStack.pop();
                                            }
                                        }
                                        if (!parentStack.isEmpty()) {
                                            Integer parentRow = parentStack.peek();
                                            rowToParentRow.put(rowNum, parentRow);
                                        }
                                    }
                                }
                            } else {
                                // no hierarchy string: top level item
                                while (!parentStack.isEmpty()) {
                                    // empty the stack
                                    parentStack.pop();
                                }
                            }
                            // add row to stack for possible children
                            parentStack.push(rowNum);
                        }
                    }
                }
            } else {
                IFieldTypeRT fieldTypeRT = FieldTypeManager.getFieldTypeRT(fieldID);
                Object attributeValue = null;
                if (fieldTypeRT.isComposite() || fieldTypeRT.isMultipleValues()) {
                    String compositeOrMultipleValue = getStringCellValue(cell);
                    if (compositeOrMultipleValue == null || "".equals(compositeOrMultipleValue.trim())) {
                        workItemBean.setAttribute(fieldID, null, null);
                        continue;
                    }
                    // we suppose that all composite and multiple values are
                    // lookup values
                    // TODO refactor if that is not true
                    String[] parts;
                    if (fieldTypeRT.isMultipleValues()) {
                        parts = compositeOrMultipleValue
                                .split(CustomSelectBaseRT.OPTION_SPLITTER_VALUES_STRING);
                        List<Integer> multipleValues = new ArrayList<Integer>();
                        for (int i = 0; i < parts.length; i++) {
                            String part = parts[i];
                            Integer objectID = null;
                            try {
                                objectID = getLookupValue(part, fieldTypeRT, fieldID, systemLookups,
                                        projectSpecificLookups, serializableBeanAllowedContext, null,
                                        invalidValueHandlingMap, locale);
                            } catch (ExcelImportNotExistingCellValueException e) {
                                addGridError(gridErrorsMap, NOT_EXISTING_ERRORS, rowNum,
                                        ExcelFieldMatchBL.colNumericToLetter(columnIndex), fieldID,
                                        e.getMessage());
                            } catch (ExcelImportNotAllowedCellValueException e) {
                                addGridError(gridErrorsMap, NOT_ALLOWED_ERRORS, rowNum,
                                        ExcelFieldMatchBL.colNumericToLetter(columnIndex), fieldID,
                                        e.getMessage());
                            }
                            if (objectID != null) {
                                multipleValues.add(objectID);
                            }
                        }
                        if (!multipleValues.isEmpty()) {
                            attributeValue = multipleValues.toArray();
                            excelValueFound = true;
                        }
                    } else {
                        int numberOfParts = ((CustomCompositeBaseRT) fieldTypeRT).getNumberOfParts();
                        parts = compositeOrMultipleValue
                                .split("\\" + CustomCompositeBaseRT.PART_SPLITTER_VALUES_STRING);
                        if (parts != null && parts.length > numberOfParts) {
                            addGridError(gridErrorsMap, WRONG_COMPOSITE_SIZE, rowNum,
                                    ExcelFieldMatchBL.colNumericToLetter(columnIndex), fieldID,
                                    compositeOrMultipleValue);
                        }
                        Map<Integer, Integer> componentPartsMap = new HashMap<Integer, Integer>();
                        attributeValue = new HashMap<Integer, Object>();
                        if (parts != null) {
                            for (int i = 0; i < parts.length; i++) {
                                String part = parts[i];
                                Integer objectID = null;
                                IFieldTypeRT componentFieldType = ((CustomCompositeBaseRT) fieldTypeRT)
                                        .getCustomFieldType(i + 1);
                                if (componentFieldType != null) {
                                    try {
                                        objectID = getLookupValue(part, componentFieldType, fieldID,
                                                systemLookups, projectSpecificLookups,
                                                serializableBeanAllowedContext, componentPartsMap,
                                                invalidValueHandlingMap, locale);
                                    } catch (ExcelImportNotExistingCellValueException e) {
                                        addGridError(gridErrorsMap, NOT_EXISTING_ERRORS, rowNum,
                                                ExcelFieldMatchBL.colNumericToLetter(columnIndex), fieldID,
                                                e.getMessage());
                                    } catch (ExcelImportNotAllowedCellValueException e) {
                                        addGridError(gridErrorsMap, NOT_ALLOWED_ERRORS, rowNum,
                                                ExcelFieldMatchBL.colNumericToLetter(columnIndex), fieldID,
                                                e.getMessage());
                                    }
                                    if (objectID == null) {
                                        // workItemBean.setAttribute(fieldID,
                                        // Integer.valueOf(i+1), null);
                                        ((Map<Integer, Object>) attributeValue).put(Integer.valueOf(i + 1),
                                                null);
                                    } else {
                                        componentPartsMap.put(Integer.valueOf(i + 1), objectID);
                                        // workItemBean.setAttribute(fieldID,
                                        // Integer.valueOf(i+1), new
                                        // Object[] {objectID});
                                        ((Map<Integer, Object>) attributeValue).put(Integer.valueOf(i + 1),
                                                new Object[] { objectID });
                                        excelValueFound = true;
                                    }
                                }
                            }
                        }
                    }
                } else {
                    // simple field
                    // Object attributeValue = null;
                    try {
                        attributeValue = getAttributeValue(cell, fieldID, null, serializableBeanAllowedContext,
                                locale, invalidValueHandlingMap, systemLookups, projectSpecificLookups);
                    } catch (ExcelImportNotExistingCellValueException e) {
                        addGridError(gridErrorsMap, NOT_EXISTING_ERRORS, rowNum,
                                ExcelFieldMatchBL.colNumericToLetter(columnIndex), fieldID, e.getMessage());
                    } catch (ExcelImportNotAllowedCellValueException e) {
                        addGridError(gridErrorsMap, NOT_ALLOWED_ERRORS, rowNum,
                                ExcelFieldMatchBL.colNumericToLetter(columnIndex), fieldID, e.getMessage());
                    } catch (ExcelImportInvalidCellValueException e) {
                        addGridError(gridErrorsMap, INVALID_ERRORS, rowNum,
                                ExcelFieldMatchBL.colNumericToLetter(columnIndex), fieldID, e.getMessage());
                    }
                    if (attributeValue != null) {
                        excelValueFound = true;
                        if (possibleBottomUpFields.contains(fieldID)) {
                            TFieldConfigBean fieldConfigBean = FieldRuntimeBL
                                    .getFieldConfigForProjectIssueTypeField(
                                            projectsToIssueTypesToFieldConfigsMapForBottomUpFields, projectID,
                                            issueTypeID, fieldID);
                            Object fieldSettings = FieldRuntimeBL.getFieldSettingsForProjectIssueTypeField(
                                    projectsIssueTypesFieldSettingsMapForBottomUpFields, projectID, issueTypeID,
                                    fieldID);
                            if (fieldTypeRT.getHierarchicalBehavior(fieldID, fieldConfigBean,
                                    fieldSettings) == HIERARCHICAL_BEHAVIOR_OPTIONS.COMPUTE_BOTTOM_UP
                                    && ItemBL.hasChildren(workItemBean.getObjectID())) {
                                Date trackPlusAttributeValue = (Date) workItemBean.getAttribute(fieldID);
                                if (EqualUtils.notEqual(trackPlusAttributeValue, (Date) attributeValue)) {
                                    // add read only restrictions for start
                                    // and end date for non leaf workItems
                                    LOGGER.debug("Parent change restriction for bottom up date " + fieldID);
                                    addGridError(gridErrorsMap, NOT_EDITABLE_ERRORS, rowNum,
                                            ExcelFieldMatchBL.colNumericToLetter(columnIndex), fieldID,
                                            getStringCellValue(cell));
                                }
                            }
                            /*
                             * if
                             * (ApplicationBean.getInstance().getSiteBean
                             * ().getSummaryItemsBehavior() &&
                             * ItemBL2.hasChildren
                             * (workItemBean.getObjectID())) { Date
                             * trackPlusAttributeValue =
                             * (Date)workItemBean.getAttribute(fieldID); if
                             * (EqualUtils.notEqual(trackPlusAttributeValue,
                             * (Date)attributeValue)) { //add read only
                             * restrictions for start and end date for non
                             * leaf workItems LOGGER.debug(
                             * "Summary parent change restriction for date "
                             * + fieldID); addGridError(gridErrorsMap,
                             * NOT_EDITABLE_ERRORS, rowNum,
                             * ExcelFieldMatchBL
                             * .colNumericToLetter(columnIndex), fieldID,
                             * getStringCellValue(cell)); } }
                             */
                        }
                    }
                }
                attributeChanged = fieldTypeRT.valueModified(attributeValue,
                        workItemBean.getAttribute(fieldID));
                workItemBean.setAttribute(fieldID, null, attributeValue);
            }
            if (attributeChanged) {
                try {
                    verifyFieldRestrictions(fieldForRestriction, restrictedFields, cell, locale);
                } catch (ExcelImportNotModifiableCellValueException e) {
                    addGridError(gridErrorsMap, NOT_EDITABLE_ERRORS, rowNum,
                            ExcelFieldMatchBL.colNumericToLetter(columnIndex), fieldID, e.getMessage());
                }
            }
        }
        if (!excelValueFound) {
            // not a single excel value found in any cell from the row
            // simply neglect this row.
            // expanded row count can be greater than the number of real
            // workItem rows
            // for example when the content of some rows is deleted but the
            // rows are not deleted
            // and empty rows may remain in the excel
            LOGGER.info("The row number " + (rowNum + 1) + " contains only empty cells and will be neglected");
            continue;
        }
        // add the default values for those fields which didn't have column
        // in
        // excel sheet or have column but the value is empty or not valid
        Iterator<Integer> itrDefaultValueFields = defaultValuesMap.keySet().iterator();
        while (itrDefaultValueFields.hasNext()) {
            Integer fieldID = itrDefaultValueFields.next();
            if (/*!fieldIDToColumnIndexMap.containsKey(fieldID) ||*/workItemBean.getAttribute(fieldID,
                    null) == null) {
                if (invalidValueHandlingMap.containsKey(fieldID)) {
                    if (DEFAULT_IF_NOT_EXIST_OR_EMPTY.equals(invalidValueHandlingMap.get(fieldID))) {
                        IFieldTypeRT fieldTypeRT = FieldTypeManager.getFieldTypeRT(fieldID, null);
                        ILookup lookup = (ILookup) fieldTypeRT;
                        Integer defaultObjectID = defaultValuesMap.get(fieldID);
                        if (defaultObjectID != null) {
                            boolean allowed = lookup.lookupBeanAllowed(defaultObjectID,
                                    serializableBeanAllowedContext);
                            if (allowed) {
                                workItemBean.setAttribute(fieldID, null, defaultObjectID);
                            } else {
                                // for example when no default project
                                // and/or issue type is specified the
                                // default manager and responsible
                                // lists contain the users which are manager
                                // or responsible in any of the projects
                                // (but maybe not in all)
                                LOGGER.debug("The default value is not allowed for field " + fieldID
                                        + " on row " + rowNum);
                                // cache the show values and localized
                                // labels to spare additional database
                                // accesses
                                String showValue;
                                if (defaultShowValuesMap.containsKey(fieldID)) {
                                    showValue = defaultShowValuesMap.get(fieldID);
                                } else {
                                    showValue = fieldTypeRT.getShowValue(defaultObjectID, locale);
                                    defaultShowValuesMap.put(fieldID, showValue);
                                }
                                String localizedLabel;
                                if (defaultLocalizedFieldLabels.containsKey(fieldID)) {
                                    localizedLabel = defaultLocalizedFieldLabels.get(fieldID);
                                } else {
                                    localizedLabel = FieldRuntimeBL.getLocalizedDefaultFieldLabel(fieldID,
                                            locale);
                                    defaultLocalizedFieldLabels.put(fieldID, localizedLabel);
                                }
                                addGridError(gridErrorsMap, NOT_ALLOWED_DEFAULT_VALUES_ERRORS, rowNum,
                                        localizedLabel, fieldID, showValue);
                            }
                        }
                    }
                }
            }
        }
        workItemBeansMap.put(rowNum, workItemBean);
    }
    return workItemBeansMap;
}

From source file:com.angkorteam.framework.swagger.factory.SwaggerFactory.java

@Override
public void afterPropertiesSet() throws Exception {
    Swagger swagger = new Swagger();
    io.swagger.models.Info info = new io.swagger.models.Info();
    swagger.setInfo(info);//from   w  w w . java 2 s . com
    info.setTitle(title);
    info.setLicense(license);
    info.setContact(contact);
    info.setTermsOfService(termsOfService);
    info.setVersion(version);
    info.setDescription(description);

    swagger.setConsumes(consumes);
    swagger.setProduces(produces);
    swagger.setSchemes(schemes);
    swagger.setBasePath(basePath);
    swagger.setHost(host);
    swagger.setExternalDocs(externalDocs);

    ConfigurationBuilder config = new ConfigurationBuilder();
    Set<String> acceptablePackages = new HashSet<>();

    boolean allowAllPackages = false;

    if (resourcePackages != null && resourcePackages.length > 0) {
        for (String resourcePackage : resourcePackages) {
            if (resourcePackage != null && !"".equals(resourcePackage)) {
                acceptablePackages.add(resourcePackage);
                config.addUrls(ClasspathHelper.forPackage(resourcePackage));
            }
        }
    }

    config.setScanners(new ResourcesScanner(), new TypeAnnotationsScanner(), new SubTypesScanner());

    Reflections reflections = new Reflections(config);
    Set<Class<?>> controllers = reflections.getTypesAnnotatedWith(Controller.class);

    Set<Class<?>> output = new HashSet<Class<?>>();
    for (Class<?> cls : controllers) {
        if (allowAllPackages) {
            output.add(cls);
        } else {
            for (String pkg : acceptablePackages) {
                if (cls.getPackage().getName().startsWith(pkg)) {
                    output.add(cls);
                }
            }
        }
    }

    Map<String, Path> paths = new HashMap<>();
    swagger.setPaths(paths);
    Map<String, Model> definitions = new HashMap<>();
    swagger.setDefinitions(definitions);
    Stack<Class<?>> modelStack = new Stack<>();
    for (Class<?> controller : controllers) {
        List<String> clazzPaths = new ArrayList<>();
        RequestMapping clazzRequestMapping = controller.getDeclaredAnnotation(RequestMapping.class);
        Api api = controller.getDeclaredAnnotation(Api.class);
        if (clazzRequestMapping != null) {
            clazzPaths = lookPaths(clazzRequestMapping);
        }
        if (clazzPaths.isEmpty()) {
            clazzPaths.add("");
        }
        if (api != null) {
            if (!"".equals(api.description())) {
                for (String name : api.tags()) {
                    if (!"".equals(name)) {
                        io.swagger.models.Tag tag = new io.swagger.models.Tag();
                        tag.setDescription(api.description());
                        tag.setName(name);
                        swagger.addTag(tag);
                    }
                }
            }
        } else {
            io.swagger.models.Tag tag = new io.swagger.models.Tag();
            tag.setDescription("Unknown");
            tag.setName("Unknown");
            swagger.addTag(tag);
        }
        Method[] methods = null;
        try {
            methods = controller.getDeclaredMethods();
        } catch (NoClassDefFoundError e) {
        }
        if (methods != null && methods.length > 0) {
            for (Method method : methods) {
                RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
                ApiOperation apiOperation = method.getAnnotation(ApiOperation.class);
                ApiResponses apiResponses = method.getAnnotation(ApiResponses.class);
                ApiHeaders apiHeaders = method.getAnnotation(ApiHeaders.class);
                List<String> methodPaths = new ArrayList<>();
                if (requestMapping != null && apiOperation != null && apiResponses != null) {
                    methodPaths = lookPaths(requestMapping);
                }
                if (methodPaths.isEmpty()) {
                    methodPaths.add("");
                }
                if (requestMapping != null && apiOperation != null && apiResponses != null) {
                    for (String classPath : clazzPaths) {
                        for (String methodPath : methodPaths) {
                            RequestMethod[] requestMethods = requestMapping.method();
                            if (requestMethods == null || requestMethods.length == 0) {
                                requestMethods = RequestMethod.values();
                            }
                            Path path = new Path();
                            paths.put(classPath + methodPath, path);
                            for (RequestMethod requestMethod : requestMethods) {
                                Operation operation = new Operation();
                                operation.setDescription(apiOperation.description());
                                for (String consume : requestMapping.consumes()) {
                                    operation.addConsumes(consume);
                                }
                                for (String produce : requestMapping.produces()) {
                                    operation.addProduces(produce);
                                }
                                if (api != null) {
                                    if (!"".equals(api.description())) {
                                        for (String name : api.tags()) {
                                            if (!"".equals(name)) {
                                                operation.addTag(name);
                                            }
                                        }
                                    }
                                } else {
                                    io.swagger.models.Tag tag = new io.swagger.models.Tag();
                                    operation.addTag("Unknown");
                                }

                                if (requestMethod == RequestMethod.DELETE) {
                                    path.delete(operation);
                                } else if (requestMethod == RequestMethod.GET) {
                                    path.get(operation);
                                } else if (requestMethod == RequestMethod.HEAD) {
                                    path.head(operation);
                                } else if (requestMethod == RequestMethod.OPTIONS) {
                                    path.options(operation);
                                } else if (requestMethod == RequestMethod.PATCH) {
                                    path.patch(operation);
                                } else if (requestMethod == RequestMethod.POST) {
                                    path.post(operation);
                                } else if (requestMethod == RequestMethod.PUT) {
                                    path.put(operation);
                                }

                                if (apiHeaders != null && apiHeaders.value() != null
                                        && apiHeaders.value().length > 0) {
                                    for (ApiHeader header : apiHeaders.value()) {
                                        HeaderParameter parameter = new HeaderParameter();
                                        parameter.setName(header.name());
                                        parameter.setType("string");
                                        parameter.setDescription(header.description());
                                        parameter.setRequired(header.required());
                                        operation.addParameter(parameter);
                                    }
                                }

                                for (Parameter parameter : method.getParameters()) {
                                    PathVariable pathVariable = parameter.getAnnotation(PathVariable.class);
                                    RequestParam requestParam = parameter.getAnnotation(RequestParam.class);
                                    RequestBody requestBody = parameter.getAnnotation(RequestBody.class);
                                    RequestPart requestPart = parameter.getAnnotation(RequestPart.class);
                                    ApiParam apiParam = parameter.getAnnotation(ApiParam.class);
                                    if (apiParam != null && pathVariable != null
                                            && isSimpleScalar(parameter.getType())) {
                                        PathParameter pathParameter = new PathParameter();
                                        pathParameter.setRequired(true);
                                        pathParameter.setDescription(apiParam.description());
                                        pathParameter.setType(lookupType(parameter.getType()));
                                        pathParameter.setFormat(lookupFormat(parameter.getType(), apiParam));
                                        pathParameter.setName(pathVariable.value());
                                        operation.addParameter(pathParameter);
                                        continue;
                                    }

                                    if (requestMethod == RequestMethod.DELETE
                                            || requestMethod == RequestMethod.GET
                                            || requestMethod == RequestMethod.HEAD
                                            || requestMethod == RequestMethod.OPTIONS
                                            || requestMethod == RequestMethod.PATCH
                                            || requestMethod == RequestMethod.PUT) {
                                        if (apiParam != null && requestParam != null
                                                && isSimpleArray(parameter.getType())) {
                                            QueryParameter param = new QueryParameter();
                                            param.setRequired(requestParam.required());
                                            param.setDescription(apiParam.description());
                                            param.setType("array");
                                            if (!"".equals(requestParam.value())) {
                                                param.setName(requestParam.value());
                                            }
                                            if (!"".equals(requestParam.name())) {
                                                param.setName(requestParam.name());
                                            }
                                            param.setItems(lookupProperty(parameter.getType(), requestParam,
                                                    apiParam));
                                            operation.addParameter(param);
                                            continue;
                                        }
                                        if (apiParam != null && requestParam != null
                                                && isSimpleScalar(parameter.getType())) {
                                            QueryParameter param = new QueryParameter();
                                            param.setRequired(requestParam.required());
                                            param.setDescription(apiParam.description());
                                            param.setType(lookupType(parameter.getType()));
                                            param.setFormat(lookupFormat(parameter.getType(), apiParam));
                                            if (!"".equals(requestParam.value())) {
                                                param.setName(requestParam.value());
                                            }
                                            if (!"".equals(requestParam.name())) {
                                                param.setName(requestParam.name());
                                            }
                                            operation.addParameter(param);
                                            continue;
                                        }
                                        if (apiParam != null && requestBody != null
                                                && parameter.getType() == MultipartFile.class) {
                                            FormParameter param = new FormParameter();
                                            param.setRequired(true);
                                            param.setIn("body");
                                            param.setName("body");
                                            param.setType("file");
                                            param.setDescription(apiParam.description());
                                            operation.addConsumes("application/octet-stream");
                                            //                                                BodyParameter param = new BodyParameter();
                                            //                                                param.setRequired(requestBody.required());
                                            //                                                param.setDescription(apiParam.description());
                                            //                                                param.setName("body");
                                            //                                                ModelImpl model = new ModelImpl();
                                            //                                                model.setType("file");
                                            //                                                param.setSchema(model);
                                            operation.addParameter(param);
                                            continue;
                                        }
                                        if (apiParam != null && requestBody != null
                                                && isSimpleArray(parameter.getType())) {
                                            BodyParameter param = new BodyParameter();
                                            param.setRequired(requestBody.required());
                                            param.setDescription(apiParam.description());
                                            param.setName("body");
                                            ArrayModel model = new ArrayModel();
                                            StringProperty property = new StringProperty();
                                            property.setType(lookupType(parameter.getType()));
                                            property.setFormat(lookupFormat(parameter.getType(), apiParam));
                                            model.setItems(property);
                                            param.setSchema(model);
                                            operation.addParameter(param);
                                            continue;
                                        }
                                        if (apiParam != null && requestBody != null
                                                && isSimpleScalar(parameter.getType())) {
                                            BodyParameter param = new BodyParameter();
                                            param.setRequired(requestBody.required());
                                            param.setDescription(apiParam.description());
                                            param.setName("body");
                                            ModelImpl model = new ModelImpl();
                                            model.setType(lookupType(parameter.getType()));
                                            model.setFormat(lookupFormat(parameter.getType(), apiParam));
                                            param.setSchema(model);
                                            operation.addParameter(param);
                                            continue;
                                        }
                                        if (apiParam != null && requestBody != null
                                                && isModelArray(parameter.getType())) {
                                            BodyParameter param = new BodyParameter();
                                            param.setRequired(requestBody.required());
                                            param.setDescription(apiParam.description());
                                            param.setName("body");
                                            ArrayModel model = new ArrayModel();
                                            RefProperty property = new RefProperty();
                                            property.setType(lookupType(parameter.getType()));
                                            property.set$ref("#/definitions/"
                                                    + parameter.getType().getComponentType().getSimpleName());
                                            if (!modelStack.contains(parameter.getType().getComponentType())) {
                                                modelStack.push(parameter.getType().getComponentType());
                                            }
                                            model.setItems(property);
                                            param.setSchema(model);
                                            operation.addParameter(param);
                                            continue;
                                        }
                                        if (apiParam != null && requestBody != null
                                                && isModelScalar(parameter.getType())) {
                                            BodyParameter param = new BodyParameter();
                                            param.setRequired(requestBody.required());
                                            param.setDescription(apiParam.description());
                                            param.setName("body");
                                            RefModel model = new RefModel();
                                            model.set$ref(
                                                    "#/definitions/" + parameter.getType().getSimpleName());
                                            if (!modelStack.contains(parameter.getType())) {
                                                modelStack.push(parameter.getType());
                                            }
                                            param.setSchema(model);
                                            operation.addParameter(param);
                                            continue;
                                        }
                                    } else if (requestMethod == RequestMethod.POST) {
                                        if (apiParam != null && requestParam != null
                                                && isSimpleArray(parameter.getType())) {
                                            FormParameter param = new FormParameter();
                                            param.setRequired(requestParam.required());
                                            param.setDescription(apiParam.description());
                                            param.setType("array");
                                            if (!"".equals(requestParam.value())) {
                                                param.setName(requestParam.value());
                                            }
                                            if (!"".equals(requestParam.name())) {
                                                param.setName(requestParam.name());
                                            }
                                            param.setItems(lookupProperty(parameter.getType(), requestParam,
                                                    apiParam));
                                            operation.addParameter(param);
                                            continue;
                                        }
                                        if (apiParam != null && requestParam != null
                                                && isSimpleScalar(parameter.getType())) {
                                            FormParameter param = new FormParameter();
                                            param.setRequired(requestParam.required());
                                            param.setDescription(apiParam.description());
                                            param.setType(lookupType(parameter.getType()));
                                            param.setFormat(lookupFormat(parameter.getType(), apiParam));
                                            if (!"".equals(requestParam.value())) {
                                                param.setName(requestParam.value());
                                            }
                                            if (!"".equals(requestParam.name())) {
                                                param.setName(requestParam.name());
                                            }
                                            operation.addParameter(param);
                                            continue;
                                        }
                                        if (apiParam != null && requestPart != null
                                                && isSimpleArray(parameter.getType())) {
                                            FormParameter param = new FormParameter();
                                            param.setRequired(requestPart.required());
                                            param.setDescription(apiParam.description());
                                            param.setType("array");
                                            if (!"".equals(requestPart.value())) {
                                                param.setName(requestPart.value());
                                            }
                                            if (!"".equals(requestPart.name())) {
                                                param.setName(requestPart.name());
                                            }
                                            param.setItems(lookupProperty(parameter.getType(), requestParam,
                                                    apiParam));
                                            operation.addParameter(param);
                                            continue;
                                        }
                                        if (apiParam != null && requestPart != null
                                                && isSimpleScalar(parameter.getType())) {
                                            FormParameter param = new FormParameter();
                                            param.setRequired(requestPart.required());
                                            param.setDescription(apiParam.description());
                                            param.setType(lookupType(parameter.getType()));
                                            param.setFormat(lookupFormat(parameter.getType(), apiParam));
                                            if (!"".equals(requestPart.value())) {
                                                param.setName(requestPart.value());
                                            }
                                            if (!"".equals(requestPart.name())) {
                                                param.setName(requestPart.name());
                                            }
                                            operation.addParameter(param);
                                            continue;
                                        }
                                    }
                                }

                                for (ApiResponse apiResponse : apiResponses.value()) {
                                    if (isSimpleScalar(apiResponse.response())) {
                                        if (apiResponse.array()) {
                                            Response response = new Response();
                                            if (!"".equals(apiResponse.description())) {
                                                response.setDescription(
                                                        apiResponse.httpStatus().getReasonPhrase());
                                            } else {
                                                response.setDescription(apiResponse.description());
                                            }
                                            ArrayProperty property = new ArrayProperty();
                                            property.setItems(
                                                    lookupProperty(apiResponse.response(), apiResponse));
                                            response.setSchema(property);
                                            operation.addResponse(
                                                    String.valueOf(apiResponse.httpStatus().value()), response);
                                        } else {
                                            Response response = new Response();
                                            if ("".equals(apiResponse.description())) {
                                                response.setDescription(
                                                        apiResponse.httpStatus().getReasonPhrase());
                                            } else {
                                                response.setDescription(apiResponse.description());
                                            }
                                            response.setSchema(
                                                    lookupProperty(apiResponse.response(), apiResponse));
                                            operation.addResponse(
                                                    String.valueOf(apiResponse.httpStatus().value()), response);
                                        }
                                    } else if (isModelScalar(apiResponse.response())) {
                                        if (apiResponse.array()) {
                                            Response response = new Response();
                                            if (!"".equals(apiResponse.description())) {
                                                response.setDescription(
                                                        apiResponse.httpStatus().getReasonPhrase());
                                            } else {
                                                response.setDescription(apiResponse.description());
                                            }
                                            RefProperty property = new RefProperty();
                                            property.set$ref(
                                                    "#/definitions/" + apiResponse.response().getSimpleName());
                                            if (!modelStack.contains(apiResponse.response())) {
                                                modelStack.push(apiResponse.response());
                                            }
                                            ArrayProperty array = new ArrayProperty();
                                            array.setItems(property);
                                            response.setSchema(array);
                                            operation.addResponse(
                                                    String.valueOf(apiResponse.httpStatus().value()), response);
                                        } else {
                                            Response response = new Response();
                                            if (!"".equals(apiResponse.description())) {
                                                response.setDescription(
                                                        apiResponse.httpStatus().getReasonPhrase());
                                            } else {
                                                response.setDescription(apiResponse.description());
                                            }
                                            RefProperty property = new RefProperty();
                                            property.set$ref(
                                                    "#/definitions/" + apiResponse.response().getSimpleName());
                                            if (!modelStack.contains(apiResponse.response())) {
                                                modelStack.push(apiResponse.response());
                                            }
                                            response.setSchema(property);
                                            operation.addResponse(
                                                    String.valueOf(apiResponse.httpStatus().value()), response);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    while (!modelStack.isEmpty()) {
        Class<?> scheme = modelStack.pop();
        if (definitions.containsKey(scheme.getSimpleName())) {
            continue;
        }
        java.lang.reflect.Field[] fields = scheme.getDeclaredFields();
        if (fields != null && fields.length > 0) {
            ModelImpl model = new ModelImpl();
            model.setType("object");
            for (Field field : fields) {
                ApiProperty apiProperty = field.getDeclaredAnnotation(ApiProperty.class);
                if (apiProperty != null) {
                    if (apiProperty.array()) {
                        Class<?> type = apiProperty.model();
                        ArrayProperty property = new ArrayProperty();
                        if (isSimpleScalar(type)) {
                            property.setItems(lookupProperty(type, apiProperty));
                        } else if (isModelScalar(type)) {
                            if (!definitions.containsKey(type.getSimpleName())) {
                                modelStack.push(type);
                            }
                            RefProperty ref = new RefProperty();
                            ref.set$ref("#/definitions/" + type.getSimpleName());
                            property.setItems(ref);
                        }
                        model.addProperty(field.getName(), property);
                    } else {
                        Class<?> type = field.getType();
                        if (isSimpleScalar(type)) {
                            model.addProperty(field.getName(), lookupProperty(type, apiProperty));
                        } else if (isModelScalar(type)) {
                            if (!definitions.containsKey(type.getSimpleName())) {
                                modelStack.push(type);
                            }
                            RefProperty ref = new RefProperty();
                            ref.set$ref("#/definitions/" + type.getSimpleName());
                            model.addProperty(field.getName(), ref);
                        }
                    }
                }
            }
            definitions.put(scheme.getSimpleName(), model);
        }
    }

    this.swagger = swagger;
}

From source file:com.clark.func.Functions.java

/**
 * Checks a filename to see if it matches the specified wildcard matcher
 * allowing control over case-sensitivity.
 * <p>/*  ww  w .  j av a 2s  .  c o  m*/
 * The wildcard matcher uses the characters '?' and '*' to represent a
 * single or multiple (zero or more) wildcard characters. N.B. the sequence
 * "*?" does not work properly at present in match strings.
 * 
 * @param filename
 *            the filename to match on
 * @param wildcardMatcher
 *            the wildcard string to match against
 * @param caseSensitivity
 *            what case sensitivity rule to use, null means case-sensitive
 * @return true if the filename matches the wilcard string
 * @since Commons IO 1.3
 */
public static boolean wildcardMatch(String filename, String wildcardMatcher, IOCase caseSensitivity) {
    if (filename == null && wildcardMatcher == null) {
        return true;
    }
    if (filename == null || wildcardMatcher == null) {
        return false;
    }
    if (caseSensitivity == null) {
        caseSensitivity = IOCase.SENSITIVE;
    }
    String[] wcs = splitOnTokens(wildcardMatcher);
    boolean anyChars = false;
    int textIdx = 0;
    int wcsIdx = 0;
    Stack<int[]> backtrack = new Stack<int[]>();

    // loop around a backtrack stack, to handle complex * matching
    do {
        if (backtrack.size() > 0) {
            int[] array = backtrack.pop();
            wcsIdx = array[0];
            textIdx = array[1];
            anyChars = true;
        }

        // loop whilst tokens and text left to process
        while (wcsIdx < wcs.length) {

            if (wcs[wcsIdx].equals("?")) {
                // ? so move to next text char
                textIdx++;
                if (textIdx > filename.length()) {
                    break;
                }
                anyChars = false;

            } else if (wcs[wcsIdx].equals("*")) {
                // set any chars status
                anyChars = true;
                if (wcsIdx == wcs.length - 1) {
                    textIdx = filename.length();
                }

            } else {
                // matching text token
                if (anyChars) {
                    // any chars then try to locate text token
                    textIdx = caseSensitivity.checkIndexOf(filename, textIdx, wcs[wcsIdx]);
                    if (textIdx == -1) {
                        // token not found
                        break;
                    }
                    int repeat = caseSensitivity.checkIndexOf(filename, textIdx + 1, wcs[wcsIdx]);
                    if (repeat >= 0) {
                        backtrack.push(new int[] { wcsIdx, repeat });
                    }
                } else {
                    // matching from current position
                    if (!caseSensitivity.checkRegionMatches(filename, textIdx, wcs[wcsIdx])) {
                        // couldnt match token
                        break;
                    }
                }

                // matched text token, move text index to end of matched
                // token
                textIdx += wcs[wcsIdx].length();
                anyChars = false;
            }

            wcsIdx++;
        }

        // full match
        if (wcsIdx == wcs.length && textIdx == filename.length()) {
            return true;
        }

    } while (backtrack.size() > 0);

    return false;
}

From source file:net.rptools.maptool.client.MapToolLineParser.java

public String parseLine(MapToolVariableResolver res, Token tokenInContext, String line,
        MapToolMacroContext context) throws ParserException {
    if (line == null) {
        return "";
    }//from   w w  w . j  a v a 2 s  . c  om
    line = line.trim();
    if (line.length() == 0) {
        return "";
    }
    Stack<Token> contextTokenStack = new Stack<Token>();
    enterContext(context);
    MapToolVariableResolver resolver = null;
    boolean resolverInitialized = false;
    String opts = null;
    String roll = null;
    try {
        // Keep the same variable context for this line
        resolver = (res == null) ? new MapToolVariableResolver(tokenInContext) : res;
        resolverInitialized = resolver.initialize();
        StringBuilder builder = new StringBuilder();
        int start = 0;
        List<InlineRollMatch> matches = this.locateInlineRolls(line);

        for (InlineRollMatch match : matches) {
            builder.append(line.substring(start, match.getStart())); // add everything before the roll

            start = match.getEnd() + 1;
            // These variables will hold data extracted from the roll options.
            Output output;
            if (MapTool.useToolTipsForUnformatedRolls()) {
                output = Output.TOOLTIP;
            } else {
                output = Output.EXPANDED;
            }
            String text = null; // used by the T option
            HashSet<String> outputOpts = new HashSet<String>();
            OutputLoc outputTo = OutputLoc.CHAT;

            LoopType loopType = LoopType.NO_LOOP;
            int loopStart = 0, loopEnd = 0, loopStep = 1;
            int loopCount = 0;
            String loopSep = null;
            String loopVar = null, loopCondition = null;
            List<String> foreachList = new ArrayList<String>();

            BranchType branchType = BranchType.NO_BRANCH;
            Object branchCondition = null;

            CodeType codeType = CodeType.NO_CODE;
            String macroName = null;

            String frameName = null;
            String frameOpts = null;

            if (match.getMatch().startsWith("[")) {
                opts = match.getOpt();
                roll = match.getRoll();
                if (opts != null) {
                    // Turn the opts string into a list of OptionInfo objects.
                    List<OptionInfo> optionList = null;
                    try {
                        optionList = getRollOptionList(opts);
                    } catch (RollOptionException roe) {
                        throw doError(roe.msg, opts, roll);
                    }

                    // Scan the roll options and prepare variables for later use
                    for (OptionInfo option : optionList) {
                        String error = null;
                        /*
                         * TODO: If you're adding a new option, add a new
                         * case here to collect info from the parameters. If
                         * your option uses parameters, use the
                         * option.getXxxParam() methods to get the text or
                         * parsed values of the parameters.
                         */
                        switch (option.optionType) {

                        ///////////////////////////////////////////////////
                        // OUTPUT FORMAT OPTIONS
                        ///////////////////////////////////////////////////
                        case HIDDEN:
                            output = Output.NONE;
                            break;
                        case RESULT:
                            output = Output.RESULT;
                            break;
                        case EXPANDED:
                            output = Output.EXPANDED;
                            break;
                        case UNFORMATTED:
                            output = Output.UNFORMATTED;
                            outputOpts.add("u");
                            break;
                        case TOOLTIP:
                            // T(display_text)
                            output = Output.TOOLTIP;
                            text = option.getStringParam(0);
                            break;

                        ///////////////////////////////////////////////////
                        // VISIBILITY OPTIONS
                        ///////////////////////////////////////////////////
                        case GM:
                            outputOpts.add("g");
                            break;
                        case SELF:
                            outputOpts.add("s");
                            break;
                        case WHISPER:
                            outputOpts.add("w");
                            for (int i = 0; i < option.getParamCount(); i++) {
                                String arg = parseExpression(resolver, tokenInContext, option.getStringParam(i))
                                        .getValue().toString();
                                if (arg.trim().startsWith("[")) {
                                    Object json = JSONMacroFunctions.convertToJSON(arg);
                                    if (json instanceof JSONArray) {
                                        for (Object name : (JSONArray) json) {
                                            outputOpts.add("w:" + name.toString().toLowerCase());
                                        }
                                    }
                                } else
                                    outputOpts.add("w:" + arg.toLowerCase());
                            }
                            break;

                        ///////////////////////////////////////////////////
                        // TOOLTIP VISIBILITY OPTIONS
                        ///////////////////////////////////////////////////
                        case GMTT:
                            outputOpts.add("gt");
                            break;
                        case SELFTT:
                            outputOpts.add("st");
                            break;

                        ///////////////////////////////////////////////////
                        // LOOP OPTIONS
                        ///////////////////////////////////////////////////
                        case COUNT:
                            // COUNT(num [, sep])
                            loopType = LoopType.COUNT;
                            error = null;
                            try {
                                loopCount = option.getParsedIntParam(0, resolver, tokenInContext);
                                if (loopCount < 0)
                                    error = I18N.getText("lineParser.countNonNeg", loopCount);
                            } catch (ParserException pe) {
                                error = I18N.getText("lineParser.errorProcessingOpt", "COUNT", pe.getMessage());
                            }
                            loopSep = option.getStringParam(1);

                            if (error != null)
                                throw doError(error, opts, roll);
                            break;

                        case FOR:
                            // FOR(var, start, end [, step [, sep]])
                            loopType = LoopType.FOR;
                            error = null;
                            try {
                                loopVar = option.getIdentifierParam(0);
                                loopStart = option.getParsedIntParam(1, resolver, tokenInContext);
                                loopEnd = option.getParsedIntParam(2, resolver, tokenInContext);
                                try {
                                    loopStep = option.getParsedIntParam(3, resolver, tokenInContext);
                                } catch (ParserException pe) {
                                    // Build a more informative error message for this common mistake
                                    String msg = pe.getMessage();
                                    msg = msg + " " + I18N.getText("lineParser.nonDefLoopSep");
                                    throw new ParserException(msg);
                                }
                                loopSep = option.getStringParam(4);
                                if (loopStep != 0)
                                    loopCount = Math.max(1, (int) Math.ceil(
                                            Math.abs((double) (loopEnd - loopStart) / (double) loopStep)));

                                if (loopVar.equalsIgnoreCase(""))
                                    error = I18N.getText("lineParser.forVarMissing");
                                if (loopStep == 0)
                                    error = I18N.getText("lineParser.forNoZeroStep");
                                if ((loopEnd <= loopStart && loopStep > 0)
                                        || (loopEnd >= loopStart && loopStep < 0))
                                    loopCount = 0;
                            } catch (ParserException pe) {
                                error = I18N.getText("lineParser.errorProcessingOpt", "FOR", pe.getMessage());
                            }

                            if (error != null)
                                throw doError(error, opts, roll);
                            break;

                        case FOREACH:
                            // FOREACH(var, list [, outputDelim [, inputDelim]])
                            loopType = LoopType.FOREACH;
                            error = null;
                            try {
                                loopVar = option.getIdentifierParam(0);
                                String listString = option.getParsedParam(1, resolver, tokenInContext)
                                        .toString();
                                loopSep = option.getStringParam(2);
                                String listDelim = option.getStringParam(3);
                                if (listDelim.trim().startsWith("\"")) {
                                    listDelim = parseExpression(resolver, tokenInContext, listDelim).getValue()
                                            .toString();
                                }

                                foreachList = null;
                                if (listString.trim().startsWith("{") || listString.trim().startsWith("[")) {
                                    // if String starts with [ or { it is JSON -- try to treat it as a JSON String
                                    Object obj = JSONMacroFunctions.convertToJSON(listString);
                                    if (obj != null) {
                                        foreachList = new ArrayList<String>();
                                        if (obj instanceof JSONArray) {
                                            for (Object o : ((JSONArray) obj).toArray()) {
                                                foreachList.add(o.toString());
                                            }
                                        } else {
                                            @SuppressWarnings("unchecked")
                                            Set<String> keySet = ((JSONObject) obj).keySet();
                                            foreachList.addAll(keySet);
                                        }
                                    }
                                }

                                // If we still dont have a list treat it list a string list
                                if (foreachList == null) {
                                    foreachList = new ArrayList<String>();
                                    StrListFunctions.parse(listString, foreachList, listDelim);
                                }
                                loopCount = foreachList.size();

                                if (loopVar.equalsIgnoreCase(""))
                                    error = I18N.getText("lineParser.foreachVarMissing");
                            } catch (ParserException pe) {
                                error = I18N.getText("lineParser.errorProcessingOpt", "FOREACH",
                                        pe.getMessage());
                            }

                            if (error != null)
                                throw doError(error, opts, roll);
                            break;

                        case WHILE:
                            // WHILE(cond [, sep])
                            loopType = LoopType.WHILE;
                            loopCondition = option.getStringParam(0);
                            loopSep = option.getStringParam(1);
                            break;

                        ///////////////////////////////////////////////////
                        // BRANCH OPTIONS
                        ///////////////////////////////////////////////////
                        case IF:
                            // IF(condition)
                            branchType = BranchType.IF;
                            branchCondition = option.getStringParam(0);
                            break;
                        case SWITCH:
                            // SWITCH(condition)
                            branchType = BranchType.SWITCH;
                            branchCondition = option.getObjectParam(0);
                            break;

                        ///////////////////////////////////////////////////
                        // DIALOG AND FRAME OPTIONS
                        ///////////////////////////////////////////////////
                        case FRAME:
                            codeType = CodeType.CODEBLOCK;
                            frameName = option.getParsedParam(0, resolver, tokenInContext).toString();
                            frameOpts = option.getParsedParam(1, resolver, tokenInContext).toString();
                            outputTo = OutputLoc.FRAME;
                            break;
                        case DIALOG:
                            codeType = CodeType.CODEBLOCK;
                            frameName = option.getParsedParam(0, resolver, tokenInContext).toString();
                            frameOpts = option.getParsedParam(1, resolver, tokenInContext).toString();
                            outputTo = OutputLoc.DIALOG;
                            break;
                        ///////////////////////////////////////////////////
                        // CODE OPTIONS
                        ///////////////////////////////////////////////////
                        case MACRO:
                            // MACRO("macroName@location")
                            codeType = CodeType.MACRO;
                            macroName = option.getStringParam(0);
                            break;
                        case CODE:
                            codeType = CodeType.CODEBLOCK;
                            break;
                        ///////////////////////////////////////////////////
                        // MISC OPTIONS
                        ///////////////////////////////////////////////////
                        case TOKEN:
                            if (!isMacroTrusted()) {
                                throw new ParserException(I18N.getText("macro.function.roll.noPerm"));
                            }
                            Token newToken = MapTool.getFrame().getCurrentZoneRenderer().getZone().resolveToken(
                                    option.getParsedParam(0, resolver, tokenInContext).toString());
                            if (newToken != null) {
                                contextTokenStack.push(resolver.getTokenInContext());
                                resolver.setTokenIncontext(newToken);
                            }
                            break;
                        default:
                            // should never happen
                            log.error(I18N.getText("lineParser.badOptionFound", opts, roll));
                            throw doError("lineParser.badOptionFound", opts, roll);
                        }
                    }
                }

                // Now that the options have been dealt with, process the body of the roll.
                // We deal with looping first, then branching, then deliver the output.
                StringBuilder expressionBuilder = new StringBuilder();
                int iteration = 0;
                boolean doLoop = true;
                while (doLoop) {
                    int loopConditionValue;
                    Integer branchConditionValue = null;
                    Object branchConditionParsed = null;

                    // Process loop settings
                    if (iteration > maxLoopIterations) {
                        throw doError("lineParser.tooManyLoops", opts, roll);
                    }

                    if (loopType != LoopType.NO_LOOP) {
                        // We only update roll.count in a loop statement.  This allows simple nested 
                        // statements to inherit roll.count from the outer statement.
                        resolver.setVariable("roll.count", iteration);
                    }

                    switch (loopType) {
                    /*
                     * TODO: If you're adding a new looping option, add a
                     * new case to handle the iteration
                     */
                    case NO_LOOP:
                        if (iteration > 0) { // stop after first iteration
                            doLoop = false;
                        }
                        break;
                    case COUNT:
                        if (iteration == loopCount) {
                            doLoop = false;
                        }
                        break;
                    case FOR:
                        if (iteration != loopCount) {
                            resolver.setVariable(loopVar, new BigDecimal(loopStart + loopStep * iteration));
                        } else {
                            doLoop = false;
                            resolver.setVariable(loopVar, null);
                        }
                        break;
                    case FOREACH:
                        if (iteration != loopCount) {
                            String item = foreachList.get(iteration);
                            resolver.setVariable(loopVar, item);
                        } else {
                            doLoop = false;
                            resolver.setVariable(loopVar, null);
                        }
                        break;
                    case WHILE:
                        // This is a hack to get around a bug with the parser's comparison operators.
                        // The InlineTreeFormatter class in the parser chokes on comparison operators, because they're
                        // not listed in the operator precedence table.
                        //
                        // The workaround is that "non-deterministic" functions fully evaluate their arguments,
                        // so the comparison operators are reduced to a number by the time the buggy code is reached.
                        // The if() function defined in dicelib is such a function, so we use it here to eat
                        // any comparison operators.
                        String hackCondition = (loopCondition == null) ? null
                                : String.format("if(%s, 1, 0)", loopCondition);
                        // Stop loop if the while condition is false
                        try {
                            Result result = parseExpression(resolver, tokenInContext, hackCondition);
                            loopConditionValue = ((Number) result.getValue()).intValue();
                            if (loopConditionValue == 0) {
                                doLoop = false;
                            }
                        } catch (Exception e) {
                            throw doError(I18N.getText("lineParser.invalidWhile", loopCondition), opts, roll);
                        }
                        break;
                    }

                    // Output the loop separator
                    if (doLoop && iteration != 0 && output != Output.NONE) {
                        expressionBuilder.append(parseExpression(resolver, tokenInContext, loopSep).getValue());
                    }

                    if (!doLoop) {
                        break;
                    }

                    iteration++;

                    // Extract the appropriate branch to evaluate.

                    // Evaluate the branch condition/expression
                    if (branchCondition != null) {
                        // This is a similar hack to the one used for the loopCondition above.
                        String hackCondition = (branchCondition == null) ? null : branchCondition.toString();
                        if (branchType == BranchType.IF) {
                            hackCondition = (hackCondition == null) ? null
                                    : String.format("if(%s, 1, 0)", hackCondition);
                        }
                        Result result = null;
                        try {
                            result = parseExpression(resolver, tokenInContext, hackCondition);
                        } catch (Exception e) {
                            throw doError(I18N.getText("lineParser.invalidCondition", branchType.toString(),
                                    branchCondition.toString()), opts, roll);
                        }
                        branchConditionParsed = result.getValue();
                        if (branchConditionParsed instanceof Number) {
                            branchConditionValue = ((Number) branchConditionParsed).intValue();
                        }
                    }

                    // Set up regexes for scanning through the branches.
                    // branchRegex then defines one matcher group for the parseable content of the branch.
                    String rollBranch = roll;
                    String branchRegex, branchSepRegex, branchLastSepRegex;
                    if (codeType != CodeType.CODEBLOCK) {
                        // matches any text not containing a ";" (skipping over strings) 
                        String noCodeRegex = "((?:[^\";]|\"[^\"]*\"|'[^']*')*)";
                        branchRegex = noCodeRegex;
                        branchSepRegex = ";";
                        branchLastSepRegex = ";?"; // The last clause doesn't have to end with a separator
                    } else {
                        // matches text inside braces "{...}", skipping over strings (one level of {} nesting allowed)
                        String codeRegex = "\\{((?:[^{}\"]|\"[^\"]*\"|'[^']*'|\\{(?:[^}\"]|\"[^\"]*\"|'[^']*')*})*)}";
                        branchRegex = codeRegex;
                        branchSepRegex = ";";
                        branchLastSepRegex = ";?"; // The last clause doesn't have to end with a separator
                    }

                    // Extract the branch to use
                    switch (branchType) {
                    /*
                     * TODO: If you're adding a new branching option, add a
                     * new case to extract the branch text
                     */
                    case NO_BRANCH: {
                        // There's only one branch, so our regex is very simple
                        String testRegex = String.format("^\\s*%s\\s*$", branchRegex);
                        Matcher testMatcher = Pattern.compile(testRegex).matcher(roll);
                        if (testMatcher.find()) {
                            rollBranch = testMatcher.group(1);
                        } else {
                            throw doError("lineParser.errorBodyRoll", opts, roll);
                        }
                        break;
                    }
                    case IF: {
                        // IF can have one or two branches.
                        // When there's only one branch and the condition is false, there's no output.
                        if (branchConditionValue == null) {
                            throw doError(I18N.getText("lineParser.invalidIfCond", branchCondition,
                                    branchConditionParsed.toString()), opts, roll);
                        }
                        int whichBranch = (branchConditionValue != 0) ? 0 : 1;
                        String testRegex = String.format("^\\s*%s\\s*(?:%s\\s*%s\\s*%s)?\\s*$", branchRegex,
                                branchSepRegex, branchRegex, branchLastSepRegex);
                        Matcher testMatcher = Pattern.compile(testRegex).matcher(roll);
                        if (testMatcher.find()) { // verifies that roll body is well-formed
                            rollBranch = testMatcher.group(1 + whichBranch);
                            if (rollBranch == null)
                                rollBranch = "''"; // quick-and-dirty way to get no output
                            rollBranch = rollBranch.trim();
                        } else {
                            throw doError("lineParser.ifError", opts, roll);
                        }
                        break;
                    }
                    case SWITCH: {
                        // We augment the branch regex to detect the "case xxx:" or "default:" prefixes,
                        // and search for a match.  An error is thrown if no case match is found.

                        // Regex matches 'default', 'case 123:', 'case "123":', 'case "abc":', but not 'case abc:'
                        branchRegex = "(?:case\\s*\"?((?<!\")(?:\\+|-)?[\\d]+(?!\")|(?<=\")[^\"]*(?=\"))\"?|(default))\\s*:\\s*"
                                + branchRegex;
                        String caseTarget = branchConditionParsed.toString();
                        String testRegex = String.format("^(?:\\s*%s\\s*%s\\s*)*\\s*%s\\s*%s\\s*$", branchRegex,
                                branchSepRegex, branchRegex, branchLastSepRegex);
                        Matcher testMatcher = Pattern.compile(testRegex).matcher(roll);
                        if (testMatcher.find()) { // verifies that roll body is well-formed
                            String scanRegex = String.format("\\s*%s\\s*(?:%s)?", branchRegex, branchSepRegex);
                            Matcher scanMatcher = Pattern.compile(scanRegex).matcher(roll);
                            boolean foundMatch = false;
                            while (!foundMatch && scanMatcher.find()) {
                                String caseLabel = scanMatcher.group(1); // "case (xxx):"
                                String def = scanMatcher.group(2); // "(default):"
                                String branch = scanMatcher.group(3);
                                if (def != null) {
                                    rollBranch = branch.trim();
                                    foundMatch = true;
                                    ;
                                }
                                if (caseLabel != null && caseLabel.matches(caseTarget)) {
                                    rollBranch = branch.trim();
                                    foundMatch = true;
                                }
                            }
                            if (!foundMatch) {
                                doError(I18N.getText("lineParser.switchNoMatch", caseTarget), opts, roll);
                            }
                        } else {
                            doError("lineParser.switchError", opts, roll);
                        }

                        break;
                    }
                    } // end of switch(branchType) statement

                    // Construct the output.  
                    // If a MACRO or CODE block is being used, we default to bare output as in the RESULT style.
                    // The output style NONE is also allowed in these cases.
                    Result result;
                    String output_text;
                    switch (codeType) {
                    case NO_CODE:
                        // If none of the code options are active, any of the formatting options can be used.
                        switch (output) {
                        /*
                         * TODO: If you're adding a new formatting option,
                         * add a new case to build the output
                         */
                        case NONE:
                            parseExpression(resolver, tokenInContext, rollBranch);
                            break;
                        case RESULT:
                            result = parseExpression(resolver, tokenInContext, rollBranch);
                            output_text = result != null ? result.getValue().toString() : "";
                            if (!this.isMacroTrusted()) {
                                output_text = output_text.replaceAll(
                                        "\u00AB|\u00BB|&#171;|&#187;|&laquo;|&raquo;|\036|\037", "");
                            }
                            if (outputOpts.isEmpty()) {
                                expressionBuilder.append(output_text);
                            } else {
                                outputOpts.add("r");
                                expressionBuilder.append(rollString(outputOpts, output_text));
                            }

                            break;
                        case TOOLTIP:
                            String tooltip = rollBranch + " = ";
                            output_text = null;
                            result = parseExpression(resolver, tokenInContext, rollBranch);
                            tooltip += result.getDetailExpression();
                            if (text == null) {
                                output_text = result.getValue().toString();
                            } else {
                                if (!result.getDetailExpression().equals(result.getValue().toString())) {
                                    tooltip += " = " + result.getValue();
                                }
                                resolver.setVariable("roll.result", result.getValue());
                                output_text = parseExpression(resolver, tokenInContext, text).getValue()
                                        .toString();
                            }
                            tooltip = tooltip.replaceAll("'", "&#39;");
                            expressionBuilder.append(
                                    output_text != null ? rollString(outputOpts, tooltip, output_text) : "");
                            break;
                        case EXPANDED:
                            expressionBuilder.append(rollString(outputOpts,
                                    rollBranch + " = " + expandRoll(resolver, tokenInContext, rollBranch)));
                            break;
                        case UNFORMATTED:
                            output_text = rollBranch + " = " + expandRoll(resolver, tokenInContext, rollBranch);

                            // Escape quotes so that the result can be used in a title attribute
                            output_text = output_text.replaceAll("'", "&#39;");
                            output_text = output_text.replaceAll("\"", "&#34;");

                            expressionBuilder.append(rollString(outputOpts, output_text));
                        } // end of switch(output) statement
                        break; // end of case NO_CODE in switch(codeType) statement
                    /*
                     * TODO: If you're adding a new code option, add a new
                     * case to execute the code
                     */
                    case MACRO:
                        // [MACRO("macroName@location"): args]
                        result = parseExpression(resolver, tokenInContext, macroName);
                        String callName = result.getValue().toString();
                        result = parseExpression(resolver, tokenInContext, rollBranch);
                        String macroArgs = result.getValue().toString();
                        output_text = runMacro(resolver, tokenInContext, callName, macroArgs);
                        if (output != Output.NONE) {
                            expressionBuilder.append(output_text);
                        }
                        resolver.setVariable("roll.count", iteration); // reset this because called code might change it
                        break;

                    case CODEBLOCK:
                        output_text = runMacroBlock(resolver, tokenInContext, rollBranch);
                        resolver.setVariable("roll.count", iteration); // reset this because called code might change it
                        if (output != Output.NONE) {
                            expressionBuilder.append(output_text);
                        }
                        break;
                    }
                }
                switch (outputTo) {
                case FRAME:
                    HTMLFrameFactory.show(frameName, true, frameOpts, expressionBuilder.toString());
                    break;
                case DIALOG:
                    HTMLFrameFactory.show(frameName, false, frameOpts, expressionBuilder.toString());
                    break;
                case CHAT:
                    builder.append(expressionBuilder);
                    break;
                }

                // Revert to our previous token if [token(): ] was used
                if (contextTokenStack.size() > 0) {
                    resolver.setTokenIncontext(contextTokenStack.pop());
                }
            } else if (match.getMatch().startsWith("{")) {
                roll = match.getRoll();
                Result result = parseExpression(resolver, tokenInContext, roll);
                if (isMacroTrusted()) {
                    builder.append(result != null ? result.getValue().toString() : "");
                } else {
                    builder.append(result != null ? result.getValue().toString()
                            .replaceAll("\u00AB|\u00BB|&#171;|&#187;|&laquo;|&raquo;|\036|\037", "") : "");
                }
            }
        }
        builder.append(line.substring(start));
        return builder.toString();
    } catch (AbortFunctionException e) {
        // do nothing; this exception will never generate any output
        // throw doError("macroExecutionAbort", opts == null ? "" : opts, roll == null ? line : roll);
        throw e;
    } catch (AssertFunctionException e) {
        // do nothing; this exception will never generate any output
        // throw doError("macroExecutionAssert", opts == null ? "" : opts, roll == null ? line : roll);
        throw e;
    } catch (ParserException e) {
        // do nothing, jut pass message back up
        throw e;
    } catch (Exception e) {
        log.info(line, e);
        throw doError("lineParser.errorBodyRoll", opts == null ? "" : opts, roll == null ? line : roll);
    } finally {
        exitContext();
        if (resolverInitialized) {
            // This is the top level call, time to clean up
            resolver.flush();
        }
        // If we have exited the last context let the html frame we have (potentially)
        // updated a token.
        if (contextStackEmpty()) {
            HTMLFrameFactory.tokenChanged(tokenInContext);
        }
        MapTool.getFrame().refresh(); // Repaint incase macros changed anything. 
    }
}