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.apache.tajo.engine.planner.LogicalPlanner.java

@Override
public LimitNode visitLimit(PlanContext context, Stack<Expr> stack, Limit limit) throws PlanningException {
    QueryBlock block = context.queryBlock;

    EvalNode firstFetNum;/*from w ww .java 2s  .com*/
    LogicalNode child;
    if (limit.getFetchFirstNum().getType() == OpType.Literal) {
        firstFetNum = exprAnnotator.createEvalNode(context, limit.getFetchFirstNum(),
                NameResolvingMode.RELS_ONLY);

        ////////////////////////////////////////////////////////
        // Visit and Build Child Plan
        ////////////////////////////////////////////////////////
        stack.push(limit);
        child = visit(context, stack, limit.getChild());
        stack.pop();
        ////////////////////////////////////////////////////////
    } else {
        ExprNormalizedResult normalizedResult = normalizer.normalize(context, limit.getFetchFirstNum());
        String referName = block.namedExprsMgr.addExpr(normalizedResult.baseExpr);
        block.namedExprsMgr.addNamedExprArray(normalizedResult.aggExprs);
        block.namedExprsMgr.addNamedExprArray(normalizedResult.scalarExprs);

        ////////////////////////////////////////////////////////
        // Visit and Build Child Plan
        ////////////////////////////////////////////////////////
        stack.push(limit);
        child = visit(context, stack, limit.getChild());
        stack.pop();
        ////////////////////////////////////////////////////////

        if (block.namedExprsMgr.isEvaluated(referName)) {
            firstFetNum = block.namedExprsMgr.getTarget(referName).getEvalTree();
        } else {
            NamedExpr namedExpr = block.namedExprsMgr.getNamedExpr(referName);
            firstFetNum = exprAnnotator.createEvalNode(context, namedExpr.getExpr(),
                    NameResolvingMode.SUBEXPRS_AND_RELS);
            block.namedExprsMgr.markAsEvaluated(referName, firstFetNum);
        }
    }
    LimitNode limitNode = block.getNodeFromExpr(limit);
    limitNode.setChild(child);
    limitNode.setInSchema(child.getOutSchema());
    limitNode.setOutSchema(child.getOutSchema());

    limitNode.setFetchFirst(firstFetNum.eval(null, null).asInt8());

    return limitNode;
}

From source file:org.apache.pig.backend.hadoop.executionengine.tez.plan.TezCompiler.java

private POSplit findPOSplit(TezOperator tezOp, OperatorKey splitKey) throws PlanException {
    POSplit split = (POSplit) tezOp.plan.getOperator(splitKey);
    if (split != null) {
        // The split is the leaf operator.
        return split;
    } else {/*  ww w . ja  v  a 2 s. c  o  m*/
        // The split is a nested split
        Stack<POSplit> stack = new Stack<POSplit>();
        split = (POSplit) tezOp.plan.getLeaves().get(0);
        stack.push(split);
        while (!stack.isEmpty()) {
            split = stack.pop();
            for (PhysicalPlan plan : split.getPlans()) {
                PhysicalOperator op = plan.getLeaves().get(0);
                if (op instanceof POSplit) {
                    split = (POSplit) op;
                    if (split.getOperatorKey().equals(splitKey)) {
                        return split;
                    } else {
                        stack.push(split);
                    }
                }
            }
        }
    }
    // TODO: what should be the new error code??
    throw new PlanException("Could not find the split operator " + splitKey, 2059, PigException.BUG);
}

From source file:de.betterform.agent.web.event.EventQueue.java

public List<XMLEvent> aggregateEventList() {
    // Stack is used to "navigate" through the event list
    LinkedList<XMLEvent> aggregatedFocusList = new LinkedList<XMLEvent>();
    Stack<XMLEvent> aggregatedInsertEventsStack = new Stack();
    Stack<XMLEvent> aggregatedEmbedEventsStack = new Stack();
    ArrayList<XMLEvent> aggregatedEventList = new ArrayList<XMLEvent>(eventList.size());

    for (XMLEvent xmlEvent : this.loadEmbedEventList) {
        aggregatedEventList.add(xmlEvent);
    }// www.j  a v  a 2s. co  m

    this.loadEmbedEventList.clear();

    for (int i = 0; i < eventList.size(); i++) {
        XercesXMLEvent xmlEvent = (XercesXMLEvent) eventList.get(i);

        XercesXMLEvent xmlEventToAdd = new XercesXMLEvent();
        // Map PROTOTYPE_CLONED event to betterform-insert-repeatitem or betterform-insert-itemset event
        // and copy event properties to new created XMLEvent
        if (xmlEvent.getType().equals(BetterFormEventNames.PROTOTYPE_CLONED)) {
            if (xmlEvent.getContextInfo("targetName").equals(XFormsConstants.ITEMSET)) {
                xmlEventToAdd.initXMLEvent("betterform-insert-itemset", xmlEvent.getBubbles(),
                        xmlEvent.getCancelable(), xmlEvent.getContextInfo());
            } else {
                xmlEventToAdd.initXMLEvent("betterform-insert-repeatitem", xmlEvent.getBubbles(),
                        xmlEvent.getCancelable(), xmlEvent.getContextInfo());
            }
            xmlEventToAdd.target = xmlEvent.target;
            xmlEvent.addProperty("generatedIds", new HashMap());
            aggregatedEventList.add(xmlEventToAdd);
            // push XMLEvent to Stack for further processing
            aggregatedInsertEventsStack.push(xmlEventToAdd);

        }
        // add all generated ids to surrounding betterform-insert-repeatitem or betterform-insert-itemset event
        else if (xmlEvent.getType().equals(BetterFormEventNames.ID_GENERATED)
                && aggregatedInsertEventsStack.size() > 0) {
            XMLEvent aggregatingInsertEvent = aggregatedInsertEventsStack.peek();
            ((HashMap) aggregatingInsertEvent.getContextInfo("generatedIds"))
                    .put(xmlEvent.getContextInfo("originalId"), xmlEvent.getContextInfo("targetId"));
        }
        // add insert position to surrounding betterform-insert-repeatitem or betterform-insert-itemset event
        else if (xmlEvent.getType().equals(BetterFormEventNames.ITEM_INSERTED)) {
            XMLEvent tmpEvent = aggregatedInsertEventsStack.pop();
            tmpEvent.addProperty("position", xmlEvent.getContextInfo("position"));
            tmpEvent.addProperty("label", xmlEvent.getContextInfo("label"));
            tmpEvent.addProperty("value", xmlEvent.getContextInfo("value"));

        } else if (xmlEvent.getType().equals(BetterFormEventNames.EMBED)) {
            aggregatedEventList.add(xmlEvent);
            aggregatedEmbedEventsStack.push(xmlEvent);
        } else if (xmlEvent.getType().equals(BetterFormEventNames.EMBED_DONE)) {
            aggregatedEmbedEventsStack.pop().addProperty("targetElement",
                    xmlEvent.getContextInfo("targetElement"));
            aggregatedEventList.add(xmlEvent);
        } else if (xmlEvent.getType().equals(XFormsEventNames.FOCUS)) {
            aggregatedFocusList.push(xmlEvent);
        }
        /* else if(xmlEvent.getType().equals(BetterFormEventNames.INDEX_CHANGED)){
        aggregatedFocusList.push(xmlEvent);
        }*/
        // all other events within eventList are simply copied to the new eventlist
        else {
            aggregatedEventList.add(xmlEvent);
        }
    }

    while (!aggregatedFocusList.isEmpty()) {
        aggregatedEventList.add(aggregatedFocusList.pollLast());
    }
    return aggregatedEventList;
}

From source file:org.apache.tajo.engine.planner.LogicalPlanner.java

private LogicalNode buildSetPlan(PlanContext context, Stack<Expr> stack, SetOperation setOperation)
        throws PlanningException {

    // 1. Init Phase
    LogicalPlan plan = context.plan;/*w  ww . ja va 2 s. c  om*/
    QueryBlock block = context.queryBlock;

    ////////////////////////////////////////////////////////
    // Visit and Build Left Child Plan
    ////////////////////////////////////////////////////////
    QueryBlock leftBlock = context.plan.getBlockByExpr(setOperation.getLeft());
    PlanContext leftContext = new PlanContext(context, leftBlock);
    stack.push(setOperation);
    LogicalNode leftChild = visit(leftContext, new Stack<Expr>(), setOperation.getLeft());
    stack.pop();
    // Connect left child and current blocks
    context.plan.connectBlocks(leftContext.queryBlock, context.queryBlock, BlockType.TableSubQuery);

    ////////////////////////////////////////////////////////
    // Visit and Build Right Child Plan
    ////////////////////////////////////////////////////////
    QueryBlock rightBlock = context.plan.getBlockByExpr(setOperation.getRight());
    PlanContext rightContext = new PlanContext(context, rightBlock);
    stack.push(setOperation);
    LogicalNode rightChild = visit(rightContext, new Stack<Expr>(), setOperation.getRight());
    stack.pop();
    // Connect right child and current blocks
    context.plan.connectBlocks(rightContext.queryBlock, context.queryBlock, BlockType.TableSubQuery);

    BinaryNode setOp;
    if (setOperation.getType() == OpType.Union) {
        setOp = block.getNodeFromExpr(setOperation);
    } else if (setOperation.getType() == OpType.Except) {
        setOp = block.getNodeFromExpr(setOperation);
    } else if (setOperation.getType() == OpType.Intersect) {
        setOp = block.getNodeFromExpr(setOperation);
    } else {
        throw new VerifyException("Invalid Type: " + setOperation.getType());
    }
    setOp.setLeftChild(leftChild);
    setOp.setRightChild(rightChild);

    // An union statement can be derived from two query blocks.
    // For one union statement between both relations, we can ensure that each corresponding data domain of both
    // relations are the same. However, if necessary, the schema of left query block will be used as a base schema.
    Target[] leftStrippedTargets = PlannerUtil
            .stripTarget(PlannerUtil.schemaToTargets(leftBlock.getRoot().getOutSchema()));

    setOp.setInSchema(leftChild.getOutSchema());
    Schema outSchema = PlannerUtil.targetToSchema(leftStrippedTargets);
    setOp.setOutSchema(outSchema);

    return setOp;
}

From source file:com.vmware.identity.idm.server.provider.ldap.LdapWithAdMappingsProvider.java

Set<Group> populateNestedGroups(ILdapConnectionEx connection, String dn, boolean groupNameOnly,
        Set<Group> groups, IIdmAuthStatRecorder authStatRecorder)
        throws NoSuchGroupException, InvalidPrincipalException {
    Validate.notNull(groups, "groups");

    final String ATTR_NAME_GROUP_CN = _ldapSchemaMapping
            .getGroupAttribute(IdentityStoreAttributeMapping.AttributeIds.GroupAttributeAccountName);
    final String ATTR_DESCRIPTION = _ldapSchemaMapping
            .getGroupAttribute(IdentityStoreAttributeMapping.AttributeIds.GroupAttributeDescription);
    final String ATTR_GROUP_SID = _ldapSchemaMapping
            .getGroupAttribute(IdentityStoreAttributeMapping.AttributeIds.GroupAttributeObjectId);

    ArrayList<String> attributeNames = new ArrayList<String>();
    attributeNames.add(ATTR_NAME_GROUP_CN);
    attributeNames.add(ATTR_GROUP_SID);//from w w  w  . j  a va  2 s .c  o m
    if (!groupNameOnly) {
        attributeNames.add(ATTR_DESCRIPTION);
    }

    final boolean bRecurse = (!this.useDirectGroupsOnly()) && (!this.useMatchingRuleInChain());
    final String groupSearchBaseDn = (this.useGroupBaseDnForNestedGroups()
            ? this.getStoreDataEx().getGroupBaseDn()
            : ServerUtils.getDomainDN(this.getDomain()));
    final String searchQueryTemplate = this.useMatchingRuleInChain()
            ? _ldapSchemaMapping.getNestedParentGroupsQuery()
            : _ldapSchemaMapping.getDirectParentGroupsQuery();

    if (logger.isDebugEnabled()) {
        logger.debug(String.format(
                "LdapWithAdMappingsProvider.populateNestedGroups -- GroupSearchBaseDn: %s; query template: %s",
                groupSearchBaseDn, searchQueryTemplate));
    }
    int numberOfLdapSearches = 0;

    HashSet<String> groupsProcessed = new HashSet<String>();
    Stack<String> groupsToProcess = new Stack<String>();

    if (ServerUtils.isNullOrEmpty(dn) == false) {
        groupsToProcess.push(dn);
    }

    long startTimeForAllGrups = System.nanoTime();

    while (groupsToProcess.isEmpty() == false) {
        String currentDn = groupsToProcess.pop();
        groupsProcessed.add(currentDn);

        String filter = String.format(searchQueryTemplate,
                (this.useMatchingRuleInChain() ? LdapFilterString.encodeMatchingRuleInChainDnFilter(currentDn)
                        : LdapFilterString.encode(currentDn)));

        String groupName = null;
        String groupDescription = null;
        String groupEntryObjectSid = null;

        ILdapPagedSearchResult prev_pagedResult = null;
        ILdapPagedSearchResult pagedResult = null;
        boolean isSearchFinished = false;

        try {
            int numOfQueriesPerGroup = 0;
            long startTimePerGroup = System.nanoTime();

            while (!isSearchFinished) {
                if (logger.isTraceEnabled()) {
                    logger.trace(String.format(
                            "LdapWithAdMappingsProvider.populateNestedGroups -- running connection.search_one_page( %s )",
                            filter));
                }
                pagedResult = connection.search_one_page(groupSearchBaseDn, LdapScope.SCOPE_SUBTREE, filter,
                        attributeNames, DEFAULT_PAGE_SIZE, prev_pagedResult);

                numOfQueriesPerGroup += 1;
                numberOfLdapSearches += 1;

                if (pagedResult != null) {
                    ILdapEntry[] entries = pagedResult.getEntries();
                    if ((entries != null) && (entries.length > 0)) {
                        for (ILdapEntry entry : entries) {
                            groupName = ServerUtils
                                    .getStringValue(entry.getAttributeValues(ATTR_NAME_GROUP_CN));

                            if (groupNameOnly == false) {
                                groupDescription = ServerUtils
                                        .getStringValue(entry.getAttributeValues(ATTR_DESCRIPTION));
                            }

                            byte[] resultObjectSID = ServerUtils
                                    .getBinaryValue(entry.getAttributeValues(ATTR_GROUP_SID));

                            SecurityIdentifier sid = SecurityIdentifier.build(resultObjectSID);
                            groupEntryObjectSid = sid.toString();

                            String groupDomainName = ServerUtils.getDomainFromDN(entry.getDN());

                            PrincipalId groupId = new PrincipalId(groupName, groupDomainName);
                            PrincipalId groupAlias = null;
                            GroupDetail groupDetail = null;

                            if (groupNameOnly == false) {
                                // If group lives in the registered Ad over Ldap IDP, we know the alias
                                // Otherwise, we do not know the alias for the domain where group lives.
                                if (groupDomainName.equalsIgnoreCase(this.getStoreData().getName())) {
                                    groupAlias = ServerUtils.getPrincipalAliasId(groupName, this.getAlias());
                                }

                                groupDetail = new GroupDetail(
                                        (groupDescription == null) ? "" : groupDescription);
                            }

                            Group g = new Group(groupId, groupAlias, groupEntryObjectSid, groupDetail);
                            groups.add(g);

                            if ((bRecurse == true) && (groupsProcessed.contains(entry.getDN()) == false)) {
                                groupsToProcess.add(entry.getDN());
                            }
                        }
                    }
                }
                isSearchFinished = (pagedResult == null) || (pagedResult.isSearchFinished());
                if (prev_pagedResult != null) {
                    prev_pagedResult.close();
                    prev_pagedResult = null;
                }
                prev_pagedResult = pagedResult;
                pagedResult = null;
            } // while !isSearchFinished

            // If summarizeLdapQueries is set false, log each ldap query
            if (authStatRecorder != null && !authStatRecorder.summarizeLdapQueries()) {
                authStatRecorder
                        .add(new LdapQueryStat(filter, groupSearchBaseDn, getConnectionString(connection),
                                TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTimePerGroup),
                                numOfQueriesPerGroup));
            }
        } finally {
            if (prev_pagedResult != null) {
                prev_pagedResult.close();
                prev_pagedResult = null;
            }
            if (pagedResult != null) {
                pagedResult.close();
                pagedResult = null;
            }
        }

    } // groupstoprocess not empty

    if (logger.isDebugEnabled()) {
        logger.debug(String.format("LdapWithAdMappingsProvider.populateNestedGroups -- ran [%d] ldap searches.",
                numberOfLdapSearches));
    }

    // If summarizeLdapQueries is set true, log once only with summary
    if (authStatRecorder != null && authStatRecorder.summarizeLdapQueries()) {
        authStatRecorder.add(new LdapQueryStat(searchQueryTemplate, groupSearchBaseDn,
                getConnectionString(connection),
                TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTimeForAllGrups), numberOfLdapSearches));
    }

    return groups;
}

From source file:org.apache.tajo.engine.planner.LogicalPlanner.java

@Override
public LogicalNode visitHaving(PlanContext context, Stack<Expr> stack, Having expr) throws PlanningException {
    QueryBlock block = context.queryBlock;

    ExprNormalizedResult normalizedResult = normalizer.normalize(context, expr.getQual());
    String referName = block.namedExprsMgr.addExpr(normalizedResult.baseExpr);
    block.namedExprsMgr.addNamedExprArray(normalizedResult.aggExprs);
    block.namedExprsMgr.addNamedExprArray(normalizedResult.scalarExprs);

    ////////////////////////////////////////////////////////
    // Visit and Build Child Plan
    ////////////////////////////////////////////////////////
    stack.push(expr);//from w ww .jav  a2s  .c o m
    LogicalNode child = visit(context, stack, expr.getChild());
    stack.pop();
    ////////////////////////////////////////////////////////

    HavingNode having = context.queryBlock.getNodeFromExpr(expr);
    having.setChild(child);
    having.setInSchema(child.getOutSchema());
    having.setOutSchema(child.getOutSchema());

    EvalNode havingCondition;
    if (block.namedExprsMgr.isEvaluated(referName)) {
        havingCondition = block.namedExprsMgr.getTarget(referName).getEvalTree();
    } else {
        NamedExpr namedExpr = block.namedExprsMgr.getNamedExpr(referName);
        havingCondition = exprAnnotator.createEvalNode(context, namedExpr.getExpr(),
                NameResolvingMode.SUBEXPRS_AND_RELS);
        block.namedExprsMgr.markAsEvaluated(referName, havingCondition);
    }

    // set having condition
    having.setQual(havingCondition);

    return having;
}

From source file:org.apache.pulsar.sql.presto.PulsarMetadata.java

@VisibleForTesting
static List<PulsarColumnMetadata> getColumns(String fieldName, Schema fieldSchema, Set<String> fieldTypes,
        Stack<String> fieldNames, Stack<Integer> positionIndices) {

    List<PulsarColumnMetadata> columnMetadataList = new LinkedList<>();

    if (isPrimitiveType(fieldSchema.getType())) {
        columnMetadataList.add(new PulsarColumnMetadata(fieldName,
                convertType(fieldSchema.getType(), fieldSchema.getLogicalType()), null, null, false, false,
                fieldNames.toArray(new String[fieldNames.size()]),
                positionIndices.toArray(new Integer[positionIndices.size()])));
    } else if (fieldSchema.getType() == Schema.Type.UNION) {
        boolean canBeNull = false;
        for (Schema type : fieldSchema.getTypes()) {
            if (isPrimitiveType(type.getType())) {
                PulsarColumnMetadata columnMetadata;
                if (type.getType() != Schema.Type.NULL) {
                    if (!canBeNull) {
                        columnMetadata = new PulsarColumnMetadata(fieldName,
                                convertType(type.getType(), type.getLogicalType()), null, null, false, false,
                                fieldNames.toArray(new String[fieldNames.size()]),
                                positionIndices.toArray(new Integer[positionIndices.size()]));
                    } else {
                        columnMetadata = new PulsarColumnMetadata(fieldName,
                                convertType(type.getType(), type.getLogicalType()), "field can be null", null,
                                false, false, fieldNames.toArray(new String[fieldNames.size()]),
                                positionIndices.toArray(new Integer[positionIndices.size()]));
                    }/*from ww w  .j  a  v  a2  s  .co m*/
                    columnMetadataList.add(columnMetadata);
                } else {
                    canBeNull = true;
                }
            } else {
                List<PulsarColumnMetadata> columns = getColumns(fieldName, type, fieldTypes, fieldNames,
                        positionIndices);
                columnMetadataList.addAll(columns);

            }
        }
    } else if (fieldSchema.getType() == Schema.Type.RECORD) {
        // check if we have seen this type before to prevent cyclic class definitions.
        if (!fieldTypes.contains(fieldSchema.getFullName())) {
            // add to types seen so far in traversal
            fieldTypes.add(fieldSchema.getFullName());
            List<Schema.Field> fields = fieldSchema.getFields();
            for (int i = 0; i < fields.size(); i++) {
                Schema.Field field = fields.get(i);
                fieldNames.push(field.name());
                positionIndices.push(i);
                List<PulsarColumnMetadata> columns;
                if (fieldName == null) {
                    columns = getColumns(field.name(), field.schema(), fieldTypes, fieldNames, positionIndices);
                } else {
                    columns = getColumns(String.format("%s.%s", fieldName, field.name()), field.schema(),
                            fieldTypes, fieldNames, positionIndices);

                }
                positionIndices.pop();
                fieldNames.pop();
                columnMetadataList.addAll(columns);
            }
            fieldTypes.remove(fieldSchema.getFullName());
        } else {
            log.debug("Already seen type: %s", fieldSchema.getFullName());
        }
    } else if (fieldSchema.getType() == Schema.Type.ARRAY) {

    } else if (fieldSchema.getType() == Schema.Type.MAP) {

    } else if (fieldSchema.getType() == Schema.Type.ENUM) {
        PulsarColumnMetadata columnMetadata = new PulsarColumnMetadata(fieldName,
                convertType(fieldSchema.getType(), fieldSchema.getLogicalType()), null, null, false, false,
                fieldNames.toArray(new String[fieldNames.size()]),
                positionIndices.toArray(new Integer[positionIndices.size()]));
        columnMetadataList.add(columnMetadata);

    } else if (fieldSchema.getType() == Schema.Type.FIXED) {

    } else {
        log.error("Unknown column type: {}", fieldSchema);
    }
    return columnMetadataList;
}

From source file:org.apache.tajo.engine.planner.LogicalPlanner.java

@Override
public SelectionNode visitFilter(PlanContext context, Stack<Expr> stack, Selection selection)
        throws PlanningException {
    QueryBlock block = context.queryBlock;

    ExprNormalizedResult normalizedResult = normalizer.normalize(context, selection.getQual());
    block.namedExprsMgr.addExpr(normalizedResult.baseExpr);
    if (normalizedResult.aggExprs.size() > 0 || normalizedResult.scalarExprs.size() > 0) {
        throw new VerifyException("Filter condition cannot include aggregation function");
    }//from   ww w .  j a  v a  2  s  . c  o  m

    ////////////////////////////////////////////////////////
    // Visit and Build Child Plan
    ////////////////////////////////////////////////////////
    stack.push(selection);
    LogicalNode child = visit(context, stack, selection.getChild());
    stack.pop();
    ////////////////////////////////////////////////////////

    SelectionNode selectionNode = context.queryBlock.getNodeFromExpr(selection);
    selectionNode.setChild(child);
    selectionNode.setInSchema(child.getOutSchema());
    selectionNode.setOutSchema(child.getOutSchema());

    // Create EvalNode for a search condition.
    EvalNode searchCondition = exprAnnotator.createEvalNode(context, selection.getQual(),
            NameResolvingMode.RELS_AND_SUBEXPRS);
    EvalNode simplified = context.evalOptimizer.optimize(context, searchCondition);
    // set selection condition
    selectionNode.setQual(simplified);

    return selectionNode;
}

From source file:com.joliciel.jochre.graphics.ShapeImpl.java

@Override
public Collection<BridgeCandidate> getBridgeCandidates(double maxBridgeWidth) {
    if (this.bridgeCandidates == null) {
        TreeSet<VerticalLineSegment> lines = this.getVerticalLineSegments();

        // Now, detect "bridges" which could indicate that the shape should be split

        // First, detect which spaces are "enclosed" and which touch the outer walls
        // To do this, build up a set of all inverse (white) lines
        TreeSet<VerticalLineSegment> inverseLines = new TreeSet<VerticalLineSegment>();
        int currentX = -1;
        VerticalLineSegment previousLine = null;
        for (VerticalLineSegment line : lines) {
            //LOG.debug("Checking line x = " + line.x + ", top = " + line.yTop + ", bottom = " + line.yBottom);
            if (line.x != currentX) {
                // new x-coordinate
                if (previousLine != null && previousLine.yBottom < this.getHeight() - 1) {
                    VerticalLineSegment inverseLine = new VerticalLineSegment(previousLine.x,
                            previousLine.yBottom + 1);
                    inverseLine.yBottom = this.getHeight() - 1;
                    inverseLines.add(inverseLine);
                    //LOG.debug("Adding inverse line x = " + inverseLine.x + ", top = " + inverseLine.yTop + ", bottom = " + inverseLine.yBottom);
                }//from  w ww  . j a v  a  2s  .  c o m
                if (line.yTop > 0) {
                    VerticalLineSegment inverseLine = new VerticalLineSegment(line.x, line.yTop - 1);
                    inverseLine.yTop = 0;
                    inverseLines.add(inverseLine);
                    //LOG.debug("Adding inverse line x = " + inverseLine.x + ", top = " + inverseLine.yTop + ", bottom = " + inverseLine.yBottom);
                }
                currentX = line.x;
            } else if (previousLine != null) {
                VerticalLineSegment inverseLine = new VerticalLineSegment(previousLine.x,
                        previousLine.yBottom + 1);
                inverseLine.yBottom = line.yTop - 1;
                inverseLines.add(inverseLine);
                //LOG.debug("Adding inverse line x = " + inverseLine.x + ", top = " + inverseLine.yTop + ", bottom = " + inverseLine.yBottom);
            }
            previousLine = line;
        }
        if (previousLine != null && previousLine.yBottom < this.getHeight() - 1) {
            VerticalLineSegment inverseLine = new VerticalLineSegment(previousLine.x, previousLine.yBottom + 1);
            inverseLine.yBottom = this.getHeight() - 1;
            inverseLines.add(inverseLine);
            //LOG.debug("Adding inverse line x = " + inverseLine.x + ", top = " + inverseLine.yTop + ", bottom = " + inverseLine.yBottom);
        }
        LOG.debug("inverseLines size: " + inverseLines.size());

        // Calculate neighbours for inverse lines
        for (VerticalLineSegment inverseLine : inverseLines) {
            for (VerticalLineSegment otherLine : inverseLines) {
                if (otherLine.x == inverseLine.x + 1) {
                    if (inverseLine.yTop - 1 <= otherLine.yBottom
                            && otherLine.yTop <= inverseLine.yBottom + 1) {
                        inverseLine.rightSegments.add(otherLine);
                        otherLine.leftSegments.add(inverseLine);
                    }
                }
                if (otherLine.x == inverseLine.x - 1) {
                    if (inverseLine.yTop - 1 <= otherLine.yBottom
                            && otherLine.yTop <= inverseLine.yBottom + 1) {
                        inverseLine.leftSegments.add(otherLine);
                        otherLine.rightSegments.add(inverseLine);
                    }
                }
            }
        }

        // Eliminate any white lines which somehow touch an edge
        Stack<VerticalLineSegment> lineStack = new Stack<VerticalLineSegment>();
        Set<VerticalLineSegment> outerInverseLines = new HashSet<VerticalLineSegment>();
        for (VerticalLineSegment inverseLine : inverseLines) {
            if (inverseLine.yTop == 0 || inverseLine.x == 0 || inverseLine.yBottom == this.getHeight() - 1
                    || inverseLine.x == this.getWidth() - 1)
                lineStack.push(inverseLine);
        }
        while (!lineStack.isEmpty()) {
            VerticalLineSegment inverseLine = lineStack.pop();
            if (!inverseLine.touched) {
                inverseLine.touched = true;
                outerInverseLines.add(inverseLine);
                //LOG.debug("Outer inverse line x = " + inverseLine.x + ", top = " + inverseLine.yTop + ", bottom = " + inverseLine.yBottom);

                for (VerticalLineSegment rightLine : inverseLine.rightSegments)
                    lineStack.push(rightLine);
                for (VerticalLineSegment leftLine : inverseLine.leftSegments) {
                    lineStack.push(leftLine);
                }
            }
        }
        LOG.debug("outerInverseLines size: " + outerInverseLines.size());

        Set<VerticalLineSegment> enclosedInverseLines = new HashSet<VerticalLineSegment>(inverseLines);
        enclosedInverseLines.removeAll(outerInverseLines);
        LOG.debug("enclosedInverseLines.size: " + enclosedInverseLines.size());
        if (LOG.isDebugEnabled()) {
            for (VerticalLineSegment inverseLine : enclosedInverseLines)
                LOG.debug("Enclosed inverse line x = " + inverseLine.x + ", top = " + inverseLine.yTop
                        + ", bottom = " + inverseLine.yBottom);
        }

        // Add bridge candidates
        // based on maximum line length and having exactly one neighbour on each side      
        LOG.debug("Adding bridge candidates");
        List<BridgeCandidate> candidateList = new ArrayList<BridgeCandidate>();
        for (VerticalLineSegment line : lines) {
            if (line.rightSegments.size() == 1 && line.leftSegments.size() == 1
                    && line.length() <= maxBridgeWidth) {
                // also the bridge width should be considered where two vertical lines touch each other
                // rather than for the full length of the line
                BridgeCandidate candidate = null;
                VerticalLineSegment rightLine = line.rightSegments.iterator().next();
                VerticalLineSegment leftLine = line.leftSegments.iterator().next();
                int leftTopTouch = (leftLine.yTop > line.yTop ? leftLine.yTop : line.yTop);
                int leftBottomTouch = (leftLine.yBottom < line.yBottom ? leftLine.yBottom : line.yBottom);
                int rightTopTouch = (rightLine.yTop > line.yTop ? rightLine.yTop : line.yTop);
                int rightBottomTouch = (rightLine.yBottom < line.yBottom ? rightLine.yBottom : line.yBottom);

                int rightLength = rightTopTouch - rightBottomTouch;
                int leftLength = leftTopTouch - leftBottomTouch;

                if (line.length() <= maxBridgeWidth || rightLength <= maxBridgeWidth
                        || leftLength <= maxBridgeWidth) {
                    candidate = new BridgeCandidate(this, line);

                    if (rightLength < leftLength && rightLength < line.length()) {
                        candidate.topTouch = rightTopTouch;
                        candidate.bottomTouch = rightBottomTouch;
                    } else if (leftLength < line.length()) {
                        candidate.topTouch = leftTopTouch;
                        candidate.bottomTouch = leftBottomTouch;
                    }
                    LOG.debug("Adding bridge candidate x = " + candidate.x + ", top = " + candidate.yTop
                            + ", bottom = " + candidate.yBottom);
                    candidateList.add(candidate);
                }
            }
        }
        LOG.debug("Bridge candidate size: " + candidateList.size());

        LOG.debug("Eliminating candidates with shorter neighbor");
        Set<BridgeCandidate> candidatesToEliminate = null;
        if (candidateList.size() > 0) {
            // eliminate any bridge candidates that touch a shorter bridge candidate
            candidatesToEliminate = new HashSet<BridgeCandidate>();
            for (int i = 0; i < candidateList.size() - 1; i++) {
                BridgeCandidate candidate = candidateList.get(i);
                for (int j = i + 1; j < candidateList.size(); j++) {
                    BridgeCandidate otherCandidate = candidateList.get(j);
                    if (otherCandidate.x == candidate.x + 1
                            && candidate.rightSegments.contains(otherCandidate)) {
                        if ((candidate.bridgeWidth()) <= (otherCandidate.bridgeWidth())) {
                            LOG.debug("Eliminating candidate x = " + otherCandidate.x + ", top = "
                                    + otherCandidate.yTop + ", bottom = " + otherCandidate.yBottom);
                            candidatesToEliminate.add(otherCandidate);
                        } else {
                            LOG.debug("Eliminating candidate x = " + candidate.x + ", top = " + candidate.yTop
                                    + ", bottom = " + candidate.yBottom);
                            candidatesToEliminate.add(candidate);
                        }
                    }
                }
            }
            candidateList.removeAll(candidatesToEliminate);

            LOG.debug("Bridge candidate size: " + candidateList.size());

            // To be a bridge, three additional things have to be true:
            // (A) intersection between right & left shape = null
            // (B) weight of right shape & weight of left shape > a certain threshold
            // (C) little overlap right boundary of left shape, left boundary of right shape

            LOG.debug("Eliminating candidates touching enclosed space");
            // (A) intersection between right & left shape = null
            // Intersection between right and left shape is non-null
            // if the line segment X touches an enclosed space immediately above or below
            candidatesToEliminate = new HashSet<BridgeCandidate>();
            for (BridgeCandidate candidate : candidateList) {
                boolean nullIntersection = true;
                for (VerticalLineSegment inverseLine : enclosedInverseLines) {
                    if (candidate.x == inverseLine.x) {
                        if (inverseLine.yBottom == candidate.yTop - 1
                                || inverseLine.yTop == candidate.yBottom + 1) {
                            nullIntersection = false;
                            break;
                        }
                    }
                }
                if (!nullIntersection) {
                    LOG.debug("Eliminating candidate x = " + candidate.x + ", top = " + candidate.yTop
                            + ", bottom = " + candidate.yBottom);
                    candidatesToEliminate.add(candidate);
                }
            }
            candidateList.removeAll(candidatesToEliminate);
            LOG.debug("Remaining bridge candidate size: " + candidateList.size());

            // another criterion for avoiding "false splits" is that on both side of the bridge
            // the shapes pretty rapidly expand in width both up and down
            LOG.debug("Eliminating candidates without vertical expansion on both sides");
            candidatesToEliminate = new HashSet<BridgeCandidate>();
            int expansionLimit = (int) Math.ceil(((double) this.getWidth()) / 6.0);
            for (BridgeCandidate candidate : candidateList) {
                // take into account the portion touching on the right or left
                boolean isCandidate = true;
                Stack<VerticalLineSegment> leftLines = new Stack<VerticalLineSegment>();
                Stack<Integer> leftDepths = new Stack<Integer>();
                leftLines.push(candidate);
                leftDepths.push(0);
                int leftTop = candidate.topTouch;
                int leftBottom = candidate.bottomTouch;
                while (!leftLines.isEmpty()) {
                    VerticalLineSegment line = leftLines.pop();
                    int depth = leftDepths.pop();
                    if (line.yTop < leftTop)
                        leftTop = line.yTop;
                    if (line.yBottom > leftBottom)
                        leftBottom = line.yBottom;
                    if (depth <= expansionLimit) {
                        for (VerticalLineSegment leftSegment : line.leftSegments) {
                            leftLines.push(leftSegment);
                            leftDepths.push(depth + 1);
                        }
                    }
                }
                if (leftTop == candidate.topTouch || leftBottom == candidate.bottomTouch)
                    isCandidate = false;
                if (isCandidate) {
                    Stack<VerticalLineSegment> rightLines = new Stack<VerticalLineSegment>();
                    Stack<Integer> rightDepths = new Stack<Integer>();
                    rightLines.push(candidate);
                    rightDepths.push(0);
                    int rightTop = candidate.topTouch;
                    int rightBottom = candidate.bottomTouch;
                    while (!rightLines.isEmpty()) {
                        VerticalLineSegment line = rightLines.pop();
                        int depth = rightDepths.pop();
                        if (line.yTop < rightTop)
                            rightTop = line.yTop;
                        if (line.yBottom > rightBottom)
                            rightBottom = line.yBottom;
                        if (depth <= expansionLimit) {
                            for (VerticalLineSegment rightSegment : line.rightSegments) {
                                rightLines.push(rightSegment);
                                rightDepths.push(depth + 1);
                            }
                        }
                    }
                    if (rightTop == candidate.topTouch || rightBottom == candidate.bottomTouch)
                        isCandidate = false;
                }
                if (!isCandidate) {
                    LOG.debug("Eliminating candidate x = " + candidate.x + ", top = " + candidate.yTop
                            + ", bottom = " + candidate.yBottom);
                    candidatesToEliminate.add(candidate);
                }
            }
            candidateList.removeAll(candidatesToEliminate);
            LOG.debug("Remaining bridge candidate size: " + candidateList.size());

            if (LOG.isDebugEnabled()) {
                for (VerticalLineSegment candidate : candidateList) {
                    LOG.debug("Remaining candidate x = " + candidate.x + ", top = " + candidate.yTop
                            + ", bottom = " + candidate.yBottom);
                }
            }
        }

        if (candidateList.size() > 0) {
            // (B) weight of right shape & weight of left shape > a certain threshold
            // (C) little overlap right boundary of left shape, left boundary of right shape
            // 
            // We can now divide the shape into n groups, each separated by a candidate
            // We recursively build a group until we reach a candidate
            // and indicate whether it's the right or left border of the candidate.
            // We then keep going from the candidate on to the next one
            // We keep tab of the size of each group and of its right & left boundaries
            // at the end we can easily determine the right and left boundaries of each,
            // as well as the right & left pixel weight
            List<VerticalLineGroup> groups = new ArrayList<VerticalLineGroup>();

            VerticalLineSegment firstLine = lines.first();
            lineStack = new Stack<VerticalLineSegment>();
            Stack<BridgeCandidate> candidateStack = new Stack<BridgeCandidate>();
            Stack<Boolean> fromLeftStack = new Stack<Boolean>();
            Stack<Boolean> candidateFromLeftStack = new Stack<Boolean>();
            lineStack.push(firstLine);
            fromLeftStack.push(true);
            VerticalLineGroup group = new VerticalLineGroup(this);
            List<BridgeCandidate> touchedCandidates = new ArrayList<BridgeCandidate>();
            while (!lineStack.isEmpty()) {
                while (!lineStack.isEmpty()) {
                    VerticalLineSegment line = lineStack.pop();
                    boolean fromLeft = fromLeftStack.pop();
                    if (line.touched)
                        continue;

                    line.touched = true;
                    if (candidateList.contains(line)) {
                        // a candidate!
                        LOG.debug("Touching candidate x = " + line.x + ", top = " + line.yTop + ", bottom = "
                                + line.yBottom);
                        BridgeCandidate candidate = null;
                        for (BridgeCandidate existingCandidate : candidateList) {
                            if (existingCandidate.equals(line)) {
                                candidate = existingCandidate;
                                break;
                            }
                        }

                        boolean foundCandidate = touchedCandidates.contains(candidate);

                        if (!foundCandidate) {
                            touchedCandidates.add(candidate);
                            candidateStack.push(candidate);
                            candidateFromLeftStack.push(fromLeft);
                            if (fromLeft) {
                                // coming from the left
                                group.rightCandidates.add(candidate);
                                candidate.leftGroup = group;
                            } else {
                                group.leftCandidates.add(candidate);
                                candidate.rightGroup = group;
                            }
                        }
                    } else {
                        // not a candidate
                        LOG.debug("Touching line length = " + line.length() + ", x = " + line.x + ", top = "
                                + line.yTop + ", bottom = " + line.yBottom);
                        group.pixelCount += line.length();
                        if (line.x < group.leftBoundary)
                            group.leftBoundary = line.x;
                        if (line.x > group.rightBoundary)
                            group.rightBoundary = line.x;
                        if (line.yTop < group.topBoundary)
                            group.topBoundary = line.yTop;
                        if (line.yBottom > group.bottomBoundary)
                            group.bottomBoundary = line.yBottom;
                        for (VerticalLineSegment leftLine : line.leftSegments) {
                            lineStack.push(leftLine);
                            fromLeftStack.push(false);
                        }
                        for (VerticalLineSegment rightLine : line.rightSegments) {
                            lineStack.push(rightLine);
                            fromLeftStack.push(true);
                        }
                    }
                } // no more lines in this group
                groups.add(group);
                if (!candidateStack.isEmpty()) {
                    BridgeCandidate candidate = candidateStack.pop();
                    boolean fromLeft = candidateFromLeftStack.pop();
                    //lineStack.push(candidate.line);
                    //fromLeftStack.push(fromLeft);
                    LOG.debug("*** New Group ***");
                    LOG.debug("Next candidate:  x = " + candidate.x + ", top = " + candidate.yTop
                            + ", bottom = " + candidate.yBottom);
                    group = new VerticalLineGroup(this);
                    if (fromLeft) {
                        group.leftCandidates.add(candidate);
                        candidate.rightGroup = group;
                    } else {
                        group.rightCandidates.add(candidate);
                        candidate.leftGroup = group;
                    }

                    // add this candidate's neighbours to the lineStack
                    for (VerticalLineSegment leftLine : candidate.leftSegments) {
                        lineStack.push(leftLine);
                        fromLeftStack.push(false);
                    }
                    for (VerticalLineSegment rightLine : candidate.rightSegments) {
                        lineStack.push(rightLine);
                        fromLeftStack.push(true);
                    }
                } // next candidate on candidate stack
            } // no more lines to process

            if (LOG.isDebugEnabled()) {
                LOG.debug("Found " + groups.size() + " groups");
                int i = 1;
                for (VerticalLineGroup aGroup : groups) {
                    LOG.debug("Group " + i++ + ", pixelCount: " + aGroup.pixelCount + ", leftBoundary: "
                            + aGroup.leftBoundary + ", rightBoundary: " + aGroup.rightBoundary);
                    LOG.debug("Candidates on left: ");
                    for (BridgeCandidate candidate : aGroup.leftCandidates)
                        LOG.debug("Candidate x = " + candidate.x + ", top = " + candidate.yTop + ", bottom = "
                                + candidate.yBottom);
                    LOG.debug("Candidates on right: ");
                    for (BridgeCandidate candidate : aGroup.rightCandidates)
                        LOG.debug("Candidate x = " + candidate.x + ", top = " + candidate.yTop + ", bottom = "
                                + candidate.yBottom);

                }
                LOG.debug("Found " + candidateList.size() + " candidates");
                for (BridgeCandidate candidate : candidateList) {
                    LOG.debug("Candidate x = " + candidate.x + ", top = " + candidate.yTop + ", bottom = "
                            + candidate.yBottom);
                    LOG.debug("- Left group = pixelCount: " + candidate.leftGroup.pixelCount
                            + ", leftBoundary: " + candidate.leftGroup.leftBoundary + ", rightBoundary: "
                            + candidate.leftGroup.rightBoundary);
                    LOG.debug("- Right group = pixelCount: " + candidate.rightGroup.pixelCount
                            + ", leftBoundary: " + candidate.rightGroup.leftBoundary + ", rightBoundary: "
                            + candidate.rightGroup.rightBoundary);
                }
            } // should we log?

            // calculate each candidate's pixel totals and boundaries
            for (BridgeCandidate candidate : candidateList) {
                for (VerticalLineGroup lineGroup : groups)
                    lineGroup.touched = false;
                Stack<VerticalLineGroup> groupStack = new Stack<VerticalLineGroup>();
                groupStack.push(candidate.leftGroup);
                while (!groupStack.isEmpty()) {
                    VerticalLineGroup lineGroup = groupStack.pop();
                    if (lineGroup.touched)
                        continue;
                    lineGroup.touched = true;
                    candidate.leftPixels += lineGroup.pixelCount;
                    if (lineGroup.leftBoundary < candidate.leftShapeLeftBoundary)
                        candidate.leftShapeLeftBoundary = lineGroup.leftBoundary;
                    if (lineGroup.rightBoundary > candidate.leftShapeRightBoundary)
                        candidate.leftShapeRightBoundary = lineGroup.rightBoundary;
                    for (BridgeCandidate leftCandidate : lineGroup.leftCandidates) {
                        if (!candidate.equals(leftCandidate)) {
                            candidate.leftPixels += leftCandidate.length();
                            groupStack.push(leftCandidate.leftGroup);
                        }
                    }
                    for (BridgeCandidate rightCandidate : lineGroup.rightCandidates) {
                        if (!candidate.equals(rightCandidate)) {
                            candidate.leftPixels += rightCandidate.length();
                            groupStack.push(rightCandidate.rightGroup);
                        }
                    }
                } // next left group
                groupStack.push(candidate.rightGroup);
                while (!groupStack.isEmpty()) {
                    VerticalLineGroup lineGroup = groupStack.pop();
                    if (lineGroup.touched)
                        continue;
                    lineGroup.touched = true;
                    candidate.rightPixels += lineGroup.pixelCount;
                    if (lineGroup.leftBoundary < candidate.rightShapeLeftBoundary)
                        candidate.rightShapeLeftBoundary = lineGroup.leftBoundary;
                    if (lineGroup.rightBoundary > candidate.rightShapeRightBoundary)
                        candidate.rightShapeRightBoundary = lineGroup.rightBoundary;
                    for (BridgeCandidate leftCandidate : lineGroup.leftCandidates) {
                        if (!candidate.equals(leftCandidate)) {
                            candidate.rightPixels += leftCandidate.length();
                            groupStack.push(leftCandidate.leftGroup);
                        }
                    }
                    for (BridgeCandidate rightCandidate : lineGroup.rightCandidates) {
                        if (!candidate.equals(rightCandidate)) {
                            candidate.rightPixels += rightCandidate.length();
                            groupStack.push(rightCandidate.rightGroup);
                        }
                    }
                } // next right group
            } // next candidate

        } // do we have any candidates?
        this.bridgeCandidates = candidateList;
    } // lazy load

    return this.bridgeCandidates;
}

From source file:hydrograph.engine.core.xmlparser.parametersubstitution.ParameterSubstitutor.java

private void substituteMutable(StringBuilder mutable, Stack<String> unresolvedParameters) {

    int startIndex = mutable.indexOf(VARIABLE_PREFIX);
    int endIndex = mutable.indexOf(VARIABLE_SUFFIX, startIndex);

    // return if nothing to substitute
    if (startIndex == -1 || endIndex == -1) {
        return;/* w w w .ja  v a  2s  .co  m*/
    }

    // get parameter name
    String parameterName = mutable.substring(startIndex + VARIABLE_PREFIX.length(), endIndex);

    // raise exception if parameter name is blank
    if (parameterName == null || parameterName.trim().length() == 0) {
        throw new ParameterSubstitutorException("Parameter name can not be blank. Please correct.");
    }

    parameterName = parameterName.trim();

    String parameterValue = null;

    if (resolvedParameterCache.containsKey(parameterName)) {
        // obtain value from cache if already present
        parameterValue = resolvedParameterCache.get(parameterName);
        LOG.info("cache used for " + parameterName);
    } else {

        // check if the parameter is already on the stack then raise
        // exception
        // that it is circular substitution
        if (unresolvedParameters.search(parameterName) != -1) {
            throw new ParameterSubstitutorException("Found a circular depencency between parameter "
                    + parameterName + " and " + unresolvedParameters.peek()
                    + ". Both are referencing each other and cannot be resolved. Please correct.");
        }

        // get parameter value
        parameterValue = parameterBank.getParameter(parameterName);

        // if value is null then raise exception
        if (parameterValue == null) {
            throw new ParameterSubstitutorException(
                    "No value is found for the parameter " + parameterName + " to substitute");
        }

        // if parameter key to be substituted is in quotes("") then escape
        // special characters from its value
        if (isParameterPresentInQuotes(mutable, startIndex, endIndex)) {
            parameterValue = StringEscapeUtils.escapeXml(parameterValue);
        }

        // add current parameter to stack to check for circular loop later
        unresolvedParameters.push(parameterName);

        // check of substitution if there is a parameter reference in
        // parameter
        // value(internal substitution)
        parameterValue = substitute(parameterValue, unresolvedParameters);

        // remove parameter from stack as soon as it is resolved
        unresolvedParameters.pop();

        // add resolved value to cache
        resolvedParameterCache.put(parameterName, parameterValue);
    }
    // delete parameter syntax
    mutable.delete(startIndex, endIndex + VARIABLE_SUFFIX.length());

    // insert parameter value
    mutable.insert(startIndex, parameterValue);

    // check for next substitution and do it if available
    substituteMutable(mutable, unresolvedParameters);

}