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:de.uni_koblenz.jgralab.utilities.rsa.Rsa2Tg.java

private boolean isValidBinaryEdgeClassCandidate(EdgeClass ec) {
    LocalBooleanGraphMarker alreadySeenMarker = new LocalBooleanGraphMarker(sg);
    Stack<EdgeClass> workingList = new Stack<EdgeClass>();
    workingList.add(ec);/*from   w ww. j a  v  a  2 s.c o  m*/
    alreadySeenMarker.mark(ec);
    while (!workingList.isEmpty()) {
        EdgeClass current = workingList.pop();
        alreadySeenMarker.mark(current);
        if (BinaryEdgeClass.class.isInstance(current)) {
            continue;
        }
        // a BinaryEdgeClass must have exactly two IncidenceClasses
        Set<IncidenceClass> allIncidenceClasses = getAllIncidenceClasses(current);
        if (allIncidenceClasses.size() != 2) {
            return false;
        }

        IncidenceClass firstIC = null, lastIC = null;
        for (IncidenceClass ic : allIncidenceClasses) {
            if (firstIC == null) {
                firstIC = ic;
            } else {
                lastIC = ic;
            }
        }
        if (isNestingIncidenceOrEdgeClass.isMarked(firstIC) || isNestingIncidenceOrEdgeClass.isMarked(lastIC)) {
            return false;
        }
        // both incidences have to have different directions and both
        // incidences are not abstract and the multiplicities must fit
        if (firstIC.get_direction() == lastIC.get_direction() && (firstIC.is_abstract() || lastIC.is_abstract())
                && (firstIC.get_minVerticesAtEdge() == 1 && firstIC.get_maxVerticesAtEdge() == 1
                        && lastIC.get_minVerticesAtEdge() == 1 && lastIC.get_maxVerticesAtEdge() == 1)) {
            return false;
        }

        // every subclass and superclass of a BinaryEdgeClass must be a
        // BinaryEdgeClass candidate, too
        for (SpecializesEdgeClass sec : current.getIncidentEdges(SpecializesEdgeClass.class)) {
            EdgeClass genEC = (EdgeClass) (sec.getAlpha() == current ? sec.getOmega() : sec.getAlpha());
            if (alreadySeenMarker.isMarked(genEC)) {
                continue;
            } else if (!workingList.contains(genEC) && !BinaryEdgeClass.class.isInstance(genEC)) {
                workingList.push(genEC);
            }
        }
    }
    return true;
}

From source file:de.uni_koblenz.jgralab.utilities.rsa.Rsa2Tg.java

private void checkAcyclicityOfMayBeNestedIn(Queue<GraphElementClass> topLevelNestingElements) {
    LocalIntegerVertexMarker number = new LocalIntegerVertexMarker(sg);
    LocalIntegerVertexMarker rnumber = new LocalIntegerVertexMarker(sg);
    int num = 0;//from   ww  w  . j  a  v  a2 s  .  c o m
    int rnum = 0;

    // depth first search
    Stack<GraphElementClass> stack = new Stack<GraphElementClass>();
    for (GraphElementClass root : topLevelNestingElements) {
        stack.push(root);
        while (!stack.isEmpty()) {
            GraphElementClass current = stack.pop();
            number.mark(current, ++num);
            for (MayBeNestedIn_nestingElement i : current.getIncidences(MayBeNestedIn_nestingElement.class)) {
                GraphElementClass child = (GraphElementClass) i.getThat();
                if (!number.isMarked(child)) {
                    stack.push(child);
                } else {
                    if (!rnumber.isMarked(child)) {
                        // there exists a backward arc
                        throw new ProcessingException(getParser(), getFileName(),
                                "The nesting hierarchy is not acyclic.");
                    }
                }
            }
            rnumber.mark(current, ++rnum);
        }
    }
}

From source file:org.apache.catalina.core.StandardContext.java

/**
 * Get naming context full name./*from  w  ww .  ja v  a  2s  . c o m*/
 */
private String getNamingContextName() {
    if (namingContextName == null) {
        Container parent = getParent();
        if (parent == null) {
            namingContextName = getName();
        } else {
            Stack stk = new Stack();
            StringBuffer buff = new StringBuffer();
            while (parent != null) {
                stk.push(parent.getName());
                parent = parent.getParent();
            }
            while (!stk.empty()) {
                buff.append("/" + stk.pop());
            }
            buff.append(getName());
            namingContextName = buff.toString();
        }
    }
    return namingContextName;
}

From source file:org.hellojavaer.testcase.generator.TestCaseGenerator.java

@SuppressWarnings({ "unchecked", "rawtypes" })
private static <T> T produceBean(Class<T> clazz, ControlParam countrolParam, Stack<Class> parseClassList) {
    try {//from w w w. ja v  a2  s  . co m
        T item = clazz.newInstance();
        for (PropertyDescriptor pd : BeanUtils.getPropertyDescriptors(clazz)) {
            Method writeMethod = pd.getWriteMethod();
            if (writeMethod == null || pd.getReadMethod() == null || //
                    countrolParam.getExcludeFieldList() != null
                            && countrolParam.getExcludeFieldList().contains(pd.getName())//
            ) {//
                continue;
            }
            Class fieldClazz = pd.getPropertyType();
            Long numIndex = countrolParam.getNumIndex();
            // int enumIndex = countrolParam.getEnumIndex();
            Random random = countrolParam.getRandom();
            long strIndex = countrolParam.getStrIndex();
            int charIndex = countrolParam.getCharIndex();
            Calendar time = countrolParam.getTime();
            if (TypeUtil.isBaseType(fieldClazz)) {
                if (TypeUtil.isNumberType(fieldClazz)) {
                    if (fieldClazz == Byte.class) {
                        writeMethod.invoke(item, Byte.valueOf((byte) (numIndex & 0x7F)));
                    } else if (fieldClazz == Short.class) {
                        writeMethod.invoke(item, Short.valueOf((short) (numIndex & 0x7FFF)));
                    } else if (fieldClazz == Integer.class) {
                        writeMethod.invoke(item, Integer.valueOf((int) (numIndex & 0x7FFFFFFF)));
                    } else if (fieldClazz == Long.class) {
                        writeMethod.invoke(item, Long.valueOf((long) numIndex));
                    } else if (fieldClazz == Float.class) {
                        writeMethod.invoke(item, Float.valueOf((float) numIndex));
                    } else if (fieldClazz == Double.class) {
                        writeMethod.invoke(item, Double.valueOf((double) numIndex));
                    } else if (fieldClazz == byte.class) {//
                        writeMethod.invoke(item, (byte) (numIndex & 0x7F));
                    } else if (fieldClazz == short.class) {
                        writeMethod.invoke(item, (short) (numIndex & 0x7FFF));
                    } else if (fieldClazz == int.class) {
                        writeMethod.invoke(item, (int) (numIndex & 0x7FFFFFFF));
                    } else if (fieldClazz == long.class) {
                        writeMethod.invoke(item, (long) numIndex);
                    } else if (fieldClazz == float.class) {
                        writeMethod.invoke(item, (float) numIndex);
                    } else if (fieldClazz == double.class) {
                        writeMethod.invoke(item, (double) numIndex);
                    }
                    numIndex++;
                    if (numIndex < 0) {
                        numIndex &= 0x7FFFFFFFFFFFFFFFL;
                    }
                    countrolParam.setNumIndex(numIndex);
                } else if (fieldClazz == boolean.class) {
                    writeMethod.invoke(item, random.nextBoolean());
                } else if (fieldClazz == Boolean.class) {
                    writeMethod.invoke(item, Boolean.valueOf(random.nextBoolean()));
                } else if (fieldClazz == char.class) {
                    writeMethod.invoke(item, CHAR_RANGE[charIndex]);
                    charIndex++;
                    if (charIndex >= CHAR_RANGE.length) {
                        charIndex = 0;
                    }
                    countrolParam.setCharIndex(charIndex);
                } else if (fieldClazz == Character.class) {
                    writeMethod.invoke(item, Character.valueOf(CHAR_RANGE[charIndex]));
                    charIndex++;
                    if (charIndex >= CHAR_RANGE.length) {
                        charIndex = 0;
                    }
                    countrolParam.setCharIndex(charIndex);
                } else if (fieldClazz == String.class) {
                    if (countrolParam.getUniqueFieldList() != null
                            && countrolParam.getUniqueFieldList().contains(pd.getName())) {
                        StringBuilder sb = new StringBuilder();
                        convertNum(strIndex, STRING_RANGE, countrolParam.getRandom(), sb);
                        writeMethod.invoke(item, sb.toString());
                        strIndex += countrolParam.getStrStep();
                        if (strIndex < 0) {
                            strIndex &= 0x7FFFFFFFFFFFFFFFL;
                        }
                        countrolParam.setStrIndex(strIndex);
                    } else {
                        writeMethod.invoke(item, String.valueOf(CHAR_RANGE[charIndex]));
                        charIndex++;
                        if (charIndex >= CHAR_RANGE.length) {
                            charIndex = 0;
                        }
                        countrolParam.setCharIndex(charIndex);
                    }

                } else if (fieldClazz == Date.class) {
                    writeMethod.invoke(item, time.getTime());
                    time.add(Calendar.DAY_OF_YEAR, 1);
                } else if (fieldClazz.isEnum()) {
                    int index = random.nextInt(fieldClazz.getEnumConstants().length);
                    writeMethod.invoke(item, fieldClazz.getEnumConstants()[index]);
                } else {
                    //
                    throw new RuntimeException("out of countrol Class " + fieldClazz.getName());
                }
            } else {
                parseClassList.push(fieldClazz);
                // TODO ?
                Set<Class> set = new HashSet<Class>(parseClassList);
                if (parseClassList.size() - set.size() <= countrolParam.getRecursiveCycleLimit()) {
                    Object bean = produceBean(fieldClazz, countrolParam, parseClassList);
                    writeMethod.invoke(item, bean);
                }
                parseClassList.pop();
            }
        }
        return item;
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

From source file:com.pironet.tda.SunJDKParser.java

/**
 * parse the next thread dump from the stream passed with the constructor.
 *
 * @return null if no more thread dumps were found.
 *//*from  w  ww .  ja  v  a  2  s  .co  m*/
public MutableTreeNode parseNext() {
    if (nextDump != null) {
        MutableTreeNode tmpDump = nextDump;
        nextDump = null;
        return (tmpDump);
    }
    boolean retry = false;
    String line = null;

    do {

        try {
            Map<String, String> threads = new HashMap<>();
            ThreadDumpInfo overallTDI = new ThreadDumpInfo("Dump No. " + counter++, 0);
            if (withCurrentTimeStamp) {
                overallTDI.setStartTime((new Date(System.currentTimeMillis())).toString());
            }
            DefaultMutableTreeNode threadDump = new DefaultMutableTreeNode(overallTDI);

            DefaultMutableTreeNode catThreads = new DefaultMutableTreeNode(
                    new TableCategory("Threads", IconFactory.THREADS));
            threadDump.add(catThreads);

            DefaultMutableTreeNode catWaiting = new DefaultMutableTreeNode(
                    new TableCategory("Threads waiting for Monitors", IconFactory.THREADS_WAITING));

            DefaultMutableTreeNode catSleeping = new DefaultMutableTreeNode(
                    new TableCategory("Threads sleeping on Monitors", IconFactory.THREADS_SLEEPING));

            DefaultMutableTreeNode catLocking = new DefaultMutableTreeNode(
                    new TableCategory("Threads locking Monitors", IconFactory.THREADS_LOCKING));

            // create category for monitors with disabled filtering.
            // NOTE:  These strings are "magic" in that the methods
            // TDA#displayCategory and TreeCategory#getCatComponent both
            // checks these literal strings and the behavior differs.
            DefaultMutableTreeNode catMonitors = new DefaultMutableTreeNode(
                    new TreeCategory("Monitors", IconFactory.MONITORS, false));
            DefaultMutableTreeNode catMonitorsLocks = new DefaultMutableTreeNode(
                    new TreeCategory("Monitors without locking thread", IconFactory.MONITORS_NO_LOCKS, false));
            DefaultMutableTreeNode catBlockingMonitors = new DefaultMutableTreeNode(
                    new TreeCategory("Threads blocked by Monitors", IconFactory.THREADS_LOCKING, false));

            String title = null;
            String dumpKey = null;
            StringBuffer content = null;
            boolean inLocking = false;
            boolean inSleeping = false;
            boolean inWaiting = false;
            int threadCount = 0;
            int waiting = 0;
            int locking = 0;
            int sleeping = 0;
            boolean locked = true;
            boolean finished = false;
            final MonitorMap mmap = new MonitorMap();
            final Stack<String> monitorStack = new Stack<>();
            long startTime = 0;
            int singleLineCounter = 0;
            boolean concurrentSyncsFlag = false;
            Matcher matched = getDm().getLastMatch();

            while (getBis().ready() && !finished) {
                line = getNextLine();
                lineCounter++;
                singleLineCounter++;
                if (locked) {
                    if (line.contains("Full thread dump")) {
                        locked = false;
                        if (!withCurrentTimeStamp) {
                            overallTDI.setLogLine(lineCounter);

                            if (startTime != 0) {
                                startTime = 0;
                            } else if (matched != null && matched.matches()) {

                                String parsedStartTime = matched.group(1);
                                if (!getDm().isDefaultMatches() && isMillisTimeStamp()) {
                                    try {
                                        // the factor is a hack for a bug in oc4j timestamp printing (pattern timeStamp=2342342340)
                                        if (parsedStartTime.length() < 13) {
                                            startTime = Long.parseLong(parsedStartTime)
                                                    * (long) Math.pow(10, 13 - parsedStartTime.length());
                                        } else {
                                            startTime = Long.parseLong(parsedStartTime);
                                        }
                                    } catch (NumberFormatException nfe) {
                                        startTime = 0;
                                    }
                                    if (startTime > 0) {
                                        overallTDI.setStartTime((new Date(startTime)).toString());
                                    }
                                } else {
                                    overallTDI.setStartTime(parsedStartTime);
                                }
                                matched = null;
                                getDm().resetLastMatch();
                            }
                        }
                        dumpKey = overallTDI.getName();
                    } else if (!getDm().isPatternError() && (getDm().getRegexPattern() != null)) {
                        Matcher m = getDm().checkForDateMatch(line);
                        if (m != null) {
                            matched = m;
                        }
                    }
                } else {
                    if (line.startsWith("\"")) {
                        // We are starting a group of lines for a different thread
                        // First, flush state for the previous thread (if any)
                        concurrentSyncsFlag = false;
                        String stringContent = content != null ? content.toString() : null;
                        if (title != null) {
                            threads.put(title, content.toString());
                            content.append("</pre></pre>");
                            addToCategory(catThreads, title, null, stringContent, singleLineCounter, true);
                            threadCount++;
                        }
                        if (inWaiting) {
                            addToCategory(catWaiting, title, null, stringContent, singleLineCounter, true);
                            inWaiting = false;
                            waiting++;
                        }
                        if (inSleeping) {
                            addToCategory(catSleeping, title, null, stringContent, singleLineCounter, true);
                            inSleeping = false;
                            sleeping++;
                        }
                        if (inLocking) {
                            addToCategory(catLocking, title, null, stringContent, singleLineCounter, true);
                            inLocking = false;
                            locking++;
                        }
                        singleLineCounter = 0;
                        while (!monitorStack.empty()) {
                            mmap.parseAndAddThread(monitorStack.pop(), title, content.toString());
                        }

                        // Second, initialize state for this new thread
                        title = line;
                        content = new StringBuffer("<body bgcolor=\"ffffff\"><pre><font size="
                                + TDA.getFontSizeModifier(-1) + '>');
                        content.append(line);
                        content.append('\n');
                    } else if (line.contains("at ")) {
                        content.append(line);
                        content.append('\n');
                    } else if (line.contains("java.lang.Thread.State")) {
                        content.append(line);
                        content.append('\n');
                        if (title.indexOf("t@") > 0) {
                            // in this case the title line is missing state informations
                            String state = line.substring(line.indexOf(':') + 1).trim();
                            if (state.indexOf(' ') > 0) {
                                title += " state=" + state.substring(0, state.indexOf(' '));
                            } else {
                                title += " state=" + state;
                            }
                        }
                    } else if (line.contains("Locked ownable synchronizers:")) {
                        concurrentSyncsFlag = true;
                        content.append(line);
                        content.append('\n');
                    } else if (line.contains("- waiting on")) {
                        content.append(linkifyMonitor(line));
                        monitorStack.push(line);
                        inSleeping = true;
                        content.append('\n');
                    } else if (line.contains("- parking to wait")) {
                        content.append(linkifyMonitor(line));
                        monitorStack.push(line);
                        inSleeping = true;
                        content.append('\n');
                    } else if (line.contains("- waiting to")) {
                        content.append(linkifyMonitor(line));
                        monitorStack.push(line);
                        inWaiting = true;
                        content.append('\n');
                    } else if (line.contains("- locked")) {
                        content.append(linkifyMonitor(line));
                        inLocking = true;
                        monitorStack.push(line);
                        content.append('\n');
                    } else if (line.contains("- ")) {
                        if (concurrentSyncsFlag) {
                            content.append(linkifyMonitor(line));
                            monitorStack.push(line);
                        } else {
                            content.append(line);
                        }
                        content.append('\n');
                    }

                    // last thread reached?
                    if ((line.contains("\"Suspend Checker Thread\""))
                            || (line.contains("\"VM Periodic Task Thread\""))
                            || (line.contains("<EndOfDump>"))) {
                        finished = true;
                        getBis().mark(getMarkSize());
                        if ((checkForDeadlocks(threadDump)) == 0) {
                            // no deadlocks found, set back original position.
                            getBis().reset();
                        }

                        if (!checkThreadDumpStatData(overallTDI)) {
                            // no statistical data found, set back original position.
                            getBis().reset();
                        }

                        getBis().mark(getMarkSize());
                        if (!(foundClassHistograms = checkForClassHistogram(threadDump))) {
                            getBis().reset();
                        }
                    }
                }
            }
            // last thread
            String stringContent = content != null ? content.toString() : null;
            if (title != null) {
                threads.put(title, content.toString());
                content.append("</pre></pre>");
                addToCategory(catThreads, title, null, stringContent, singleLineCounter, true);
                threadCount++;
            }
            if (inWaiting) {
                addToCategory(catWaiting, title, null, stringContent, singleLineCounter, true);
                waiting++;
            }
            if (inSleeping) {
                addToCategory(catSleeping, title, null, stringContent, singleLineCounter, true);
                sleeping++;
            }
            if (inLocking) {
                addToCategory(catLocking, title, null, stringContent, singleLineCounter, true);
                locking++;
            }
            while (!monitorStack.empty()) {
                mmap.parseAndAddThread(monitorStack.pop(), title, content.toString());
            }

            int monitorCount = mmap.size();

            int monitorsWithoutLocksCount = 0;
            int contendedMonitors = 0;
            int blockedThreads = 0;
            // dump monitors 
            if (mmap.size() > 0) {
                int[] result = dumpMonitors(catMonitors, catMonitorsLocks, mmap);
                monitorsWithoutLocksCount = result[0];
                overallTDI.setOverallThreadsWaitingWithoutLocksCount(result[1]);

                result = dumpBlockingMonitors(catBlockingMonitors, mmap);
                contendedMonitors = result[0];
                blockedThreads = result[1];
            }

            // display nodes with stuff to display
            if (waiting > 0) {
                overallTDI.setWaitingThreads((Category) catWaiting.getUserObject());
                threadDump.add(catWaiting);
            }

            if (sleeping > 0) {
                overallTDI.setSleepingThreads((Category) catSleeping.getUserObject());
                threadDump.add(catSleeping);
            }

            if (locking > 0) {
                overallTDI.setLockingThreads((Category) catLocking.getUserObject());
                threadDump.add(catLocking);
            }

            if (monitorCount > 0) {
                overallTDI.setMonitors((Category) catMonitors.getUserObject());
                threadDump.add(catMonitors);
            }

            if (contendedMonitors > 0) {
                overallTDI.setBlockingMonitors((Category) catBlockingMonitors.getUserObject());
                threadDump.add(catBlockingMonitors);
            }

            if (monitorsWithoutLocksCount > 0) {
                overallTDI.setMonitorsWithoutLocks((Category) catMonitorsLocks.getUserObject());
                threadDump.add(catMonitorsLocks);
            }
            overallTDI.setThreads((Category) catThreads.getUserObject());

            ((Category) catThreads.getUserObject())
                    .setName(catThreads.getUserObject() + " (" + threadCount + " Threads overall)");
            ((Category) catWaiting.getUserObject())
                    .setName(catWaiting.getUserObject() + " (" + waiting + " Threads waiting)");
            ((Category) catSleeping.getUserObject())
                    .setName(catSleeping.getUserObject() + " (" + sleeping + " Threads sleeping)");
            ((Category) catLocking.getUserObject())
                    .setName(catLocking.getUserObject() + " (" + locking + " Threads locking)");
            ((Category) catMonitors.getUserObject())
                    .setName(catMonitors.getUserObject() + " (" + monitorCount + " Monitors)");
            ((Category) catBlockingMonitors.getUserObject()).setName(catBlockingMonitors.getUserObject() + " ("
                    + blockedThreads + " Threads blocked by " + contendedMonitors + " Monitors)");
            ((Category) catMonitorsLocks.getUserObject()).setName(
                    catMonitorsLocks.getUserObject() + " (" + monitorsWithoutLocksCount + " Monitors)");
            // add thread dump to passed dump store.
            if ((threadCount > 0) && (dumpKey != null)) {
                threadStore.put(dumpKey.trim(), threads);
            }

            // check custom categories
            addCustomCategories(threadDump);

            return (threadCount > 0 ? threadDump : null);
        } catch (StringIndexOutOfBoundsException e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog(null,
                    "Error during parsing of a found thread dump, skipping to next one!\n"
                            + "Check for possible broken dumps, sometimes, stream flushing mixes the logged data.\n"
                            + "Error Message is \"" + e.getLocalizedMessage() + "\". \n"
                            + (line != null ? "Last line read was \"" + line + "\". \n" : ""),
                    "Error during Parsing Thread Dump", JOptionPane.ERROR_MESSAGE);
            retry = true;
        } catch (IOException e) {
            e.printStackTrace();
        }
    } while (retry);

    return (null);
}

From source file:org.apache.ojb.otm.core.ConcreteEditingContext.java

private ContextEntry insertInternal(Identity oid, Object userObject, int lock, boolean canCreate,
        Identity insertBeforeThis, Stack stack) throws LockingException {
    ContextEntry entry;/*from www.j  a v a  2 s .  co  m*/
    LockManager lockManager;
    Swizzling swizzlingStrategy;
    IndirectionHandler handler = null;
    OTMKit kit = _tx.getKit();
    // Are we building object's relations for the userObject in the transaction?
    // Otherwise we just get data from the "userObject" and put it into
    // the previously loaded/created object in the transaction
    boolean buildingObject = false;
    boolean lazySwizzle = false;

    if (lock == LockType.NO_LOCK) {
        return null;
    }

    entry = (ContextEntry) _objects.get(oid);

    if (userObject == null) {
        // invalidating object...
        _original.remove(oid);
        _checkpointed.remove(oid);
        if (entry != null) {
            entry.userObject = null;
            entry.cacheObject = null;
        }
        return entry;
    }

    lockManager = LockManager.getInstance();
    swizzlingStrategy = kit.getSwizzlingStrategy();

    handler = ProxyHelper.getIndirectionHandler(userObject);
    if ((handler != null) && handler.alreadyMaterialized()) {
        userObject = handler.getRealSubject();
        handler = null;
    }

    if ((entry == null) || (entry.userObject == null)) {
        // first insertion of the userObject into editing context
        Object swizzledObject = swizzlingStrategy.swizzle(userObject, null, _pb, this);
        entry = new ContextEntry(swizzledObject);
        if (entry.handler != null) {
            ObjectCopyStrategy copyStrategy = _tx.getKit().getCopyStrategy(oid);
            entry.cacheObject = copyStrategy.copy(userObject, _pb);
            // Assume that object exists, otherwise were the proxy came from?
            _objects.put(oid, entry);
            lockManager.ensureLock(oid, _tx, lock, _pb); // lock after _objects.put to avoid hanged locks
            entry.handler.addListener(this);
        } else {
            Object origCacheObj = _pb.getObjectByIdentity(oid);

            if ((origCacheObj == null) && !canCreate) {
                // we don't create the objects by reachability
                throw new IllegalStateException(
                        "Related object is neither persistent, nor otm-depentent: " + oid);
            }
            if (origCacheObj != null) {
                entry.cacheObject = origCacheObj;
            }
            buildingObject = true;
            _objects.put(oid, entry);
            lockManager.ensureLock(oid, _tx, lock, _pb); // lock after _objects.put to avoid hanged locks

            if (userObject != null) {
                if ((origCacheObj == null) && canCreate) {
                    ObjectCopyStrategy copyStrategy = _tx.getKit().getCopyStrategy(oid);
                    entry.cacheObject = copyStrategy.copy(userObject, _pb);
                    entry.state = State.PERSISTENT_NEW;
                    if (kit.isEagerInsert(userObject) || hasBidirectionalAssociation(userObject.getClass())) {
                        _pb.store(entry.cacheObject, entry.state);
                        entry.state = State.PERSISTENT_CLEAN;
                        origCacheObj = entry.cacheObject;
                    }
                }

                if (origCacheObj != null) {
                    _original.put(oid, getFields(userObject, false, true));
                }
            }
        }
        if (insertBeforeThis != null) {
            int insertIndex = _order.indexOf(insertBeforeThis);
            _order.add(insertIndex, oid);
        } else {
            _order.add(oid);
        }
    } else {
        // The object in context is the same object attempted an insert on
        // Ensure we have the correct lock level
        lockManager.ensureLock(oid, _tx, lock, _pb);

        if (handler == null) {
            if (!swizzlingStrategy.isSameInstance(entry.userObject, userObject)) {
                // the new object contains data to deal with
                if (entry.handler != null) {
                    // materialize old object even if it is not
                    // materialized yet, because we need a place
                    // to copy the data from the new object
                    entry.userObject = entry.handler.getRealSubject();
                    entry.handler = null;
                }
                // swizzle after lockReachableObjects(), when all related objects
                // will be in the editing context
                lazySwizzle = true;
            }
        }
    }

    // perform automatic read lock for all reachable objects
    // if the inserted object is materialized
    if ((handler == null) && !stack.contains(userObject)) {
        stack.push(userObject);
        lockReachableObjects(oid, userObject, entry.cacheObject, lock, stack, buildingObject);
        stack.pop();
        if (lazySwizzle) {
            entry.userObject = swizzlingStrategy.swizzle(userObject, entry.userObject, _pb, this);
        }
    }

    return entry;
}

From source file:it.doqui.index.ecmengine.business.personalization.splitting.SplittingDbNodeServiceImpl.java

/**
 * Recursive method used to build up paths from a given node to the root.
 * <p>//  www .j  a v a2  s  .co m
 * Whilst walking up the hierarchy to the root, some nodes may have a <b>root</b> aspect.
 * Everytime one of these is encountered, a new path is farmed off, but the method
 * continues to walk up the hierarchy.
 *
 * @param currentNode the node to start from, i.e. the child node to work upwards from
 * @param currentPath the path from the current node to the descendent that we started from
 * @param completedPaths paths that have reached the root are added to this collection
 * @param assocStack the parent-child relationships traversed whilst building the path.
 *      Used to detected cyclic relationships.
 * @param primaryOnly true if only the primary parent association must be traversed.
 *      If this is true, then the only root is the top level node having no parents.
 * @throws CyclicChildRelationshipException
 */
private void prependPaths(final Node currentNode, final Path currentPath, Collection<Path> completedPaths,
        Stack<ChildAssoc> assocStack, boolean primaryOnly) throws CyclicChildRelationshipException {
    logger.debug("[SplittingDbNodeServiceImpl::prependPaths] BEGIN");

    try {
        Assert.isTrue(!isPart(currentNode), "BUG: prependPaths() on part node!");
        NodeRef currentNodeRef = currentNode.getNodeRef();

        // get the parent associations of the given node
        Collection<ChildAssoc> parentAssocs = nodeDaoService.getParentAssocs(currentNode);

        // does the node have parents
        boolean hasParents = !parentAssocs.isEmpty();

        // does the current node have a root aspect?
        boolean isRoot = currentNode.getAspects().contains(ContentModel.ASPECT_ROOT);
        boolean isStoreRoot = currentNode.getTypeQName().equals(ContentModel.TYPE_STOREROOT);

        // look for a root.  If we only want the primary root, then ignore all but the top-level root.
        if (isRoot && !(primaryOnly && hasParents)) { // exclude primary search with parents present

            // create a one-sided association reference 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 association in as the first association in the path must be a one-sided
            //   reference pointing to the root node
            ChildAssociationRef assocRef = new ChildAssociationRef(null, null, null, // Type, parent and QName
                    getRootNode(currentNode.getNodeRef().getStoreRef()));

            // create a path to save and add the 'root' association
            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(
                        isStoreRoot ? ContentModel.ASSOC_CHILDREN : first.getRef().getTypeQName(),
                        getRootNode(currentNode.getNodeRef().getStoreRef()), 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);
        }

        if (!hasParents && !isRoot) {
            throw new RuntimeException("Node without parents does not have root aspect: " + currentNodeRef);
        }

        // walk up each parent association
        for (ChildAssoc assoc : parentAssocs) {

            // does the association already exist in the stack
            if (assocStack.contains(assoc)) {
                // the association was present already
                throw new CyclicChildRelationshipException(
                        "Cyclic parent-child relationship detected: \n" + "   current node: " + currentNode
                                + "\n" + "   current path: " + currentPath + "\n" + "   next assoc: " + assoc,
                        assoc);
            }

            // do we consider only primary associations?
            if (primaryOnly && !assoc.getIsPrimary()) {
                continue;
            }

            Node realParent = getPartsContainerNode(assoc.getParent());

            // build a real association reference
            ChildAssociationRef assocRef = new ChildAssociationRef(assoc.getTypeQName(),
                    tenantService.getBaseName(realParent.getNodeRef()), assoc.getQname(),
                    tenantService.getBaseName(assoc.getChild().getNodeRef()), assoc.getIsPrimary(), -1);

            // Ordering is not important here: We are building distinct paths upwards
            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);

            // push the associations stack, recurse and pop
            assocStack.push(assoc);
            prependPaths(realParent, path, completedPaths, assocStack, primaryOnly);
            assocStack.pop();
        }
    } finally {
        logger.debug("[SplittingDbNodeServiceImpl::prependPaths] END");
    }
}

From source file:com.tmh.web.filter.xss.HtmlSanitizer.java

public static SanitizeResult sanitizer(String html, Pattern allowedTags, Pattern forbiddenTags) {
    SanitizeResult ret = new SanitizeResult();
    Stack<String> openTags = new Stack();

    List<String> tokens = tokenize(html);

    // -------------------   LOOP for every token --------------------------
    for (String token : tokens) {
        boolean isAcceptedToken = false;
        Matcher startMatcher = tagStartPattern.matcher(token);
        Matcher endMatcher = tagClosePattern.matcher(token);

        //  COMMENT    <!-- ......... -->
        if (commentPattern.matcher(token).find()) {
            ret.val = ret.val + token + (token.endsWith("-->") ? "" : "-->");
            ret.invalidTags.add(token + (token.endsWith("-->") ? "" : "-->"));
            continue;

        } //  STYLE SCRIPT   style=xss:expression
        else if (styleScriptPattern.matcher(token).find()) {
            ret.val = ret.val + token;
            ret.invalidTags.add(token);//from ww w. j a va  2  s  .co m
            continue;

            //  OPEN TAG    <tag .........>
        } else if (startMatcher.find()) {

            //tag name extraction
            String tag = startMatcher.group(1).toLowerCase();

            //-----------------------------------------------------  FORBIDDEN TAG   <script .........>
            if (forbiddenTags.matcher(tag).find()) {
                ret.invalidTags.add("<" + tag + ">");
                continue;

                // --------------------------------------------------  WELL KNOWN TAG
            } else if (allowedTags.matcher(tag).find()) {

                String cleanToken = "<" + tag;
                String tokenBody = startMatcher.group(2);

                //first test table consistency
                //table tbody tfoot thead th tr td
                if ("thead".equals(tag) || "tbody".equals(tag) || "tfoot".equals(tag) || "tr".equals(tag)) {
                    if (openTags.search("table") < 1) {
                        ret.invalidTags.add("<" + tag + ">");
                        continue;
                    }
                } else if ("td".equals(tag) || "th".equals(tag)) {
                    if (openTags.search("tr") < 1) {
                        ret.invalidTags.add("<" + tag + ">");
                        continue;
                    }
                }

                // then test properties
                Matcher attributes = attributesPattern.matcher(tokenBody);

                boolean foundURL = false; // URL flag
                while (attributes.find()) {

                    String attr = attributes.group(1).toLowerCase();
                    String val = attributes.group(2);

                    // we will accept href in case of <A>
                    if ("a".equals(tag) && "href".equals(attr)) { // <a href="......">
                        String[] customSchemes = { "http", "https" };
                        if (new UrlValidator(customSchemes).isValid(val)) {
                            foundURL = true;
                        } else {
                            // may be it is a mailto?
                            //  case <a href="mailto:pippo@pippo.com?subject=...."
                            if (val.toLowerCase().startsWith("mailto:") && val.indexOf("@") >= 0) {
                                String val1 = "http://www." + val.substring(val.indexOf("@") + 1);
                                if (new UrlValidator(customSchemes).isValid(val1)) {
                                    foundURL = true;
                                } else {
                                    ret.invalidTags.add(attr + " " + val);
                                    val = "";
                                }
                            } else {
                                ret.invalidTags.add(attr + " " + val);
                                val = "";
                            }
                        }

                    } else if (tag.matches("img|embed") && "src".equals(attr)) { // <img src="......">
                        String[] customSchemes = { "http", "https" };
                        if (new UrlValidator(customSchemes).isValid(val)) {
                            foundURL = true;
                        } else {
                            ret.invalidTags.add(attr + " " + val);
                            val = "";
                        }

                    } else if ("href".equals(attr) || "src".equals(attr)) { // <tag src/href="......">   skipped
                        ret.invalidTags.add(tag + " " + attr + " " + val);
                        continue;

                    } else if (attr.matches("width|height")) { // <tag width/height="......">
                        if (!val.toLowerCase().matches("\\d+%|\\d+$")) { // test numeric values
                            ret.invalidTags.add(tag + " " + attr + " " + val);
                            continue;
                        }

                    } else if ("style".equals(attr)) { // <tag style="......">

                        // then test properties
                        Matcher styles = stylePattern.matcher(val);
                        String cleanStyle = "";

                        while (styles.find()) {
                            String styleName = styles.group(1).toLowerCase();
                            String styleValue = styles.group(2);

                            // suppress invalid styles values
                            if (forbiddenStylePattern.matcher(styleValue).find()) {
                                ret.invalidTags.add(tag + " " + attr + " " + styleValue);
                                continue;
                            }

                            // check if valid url
                            Matcher urlStyleMatcher = urlStylePattern.matcher(styleValue);
                            if (urlStyleMatcher.find()) {
                                String[] customSchemes = { "http", "https" };
                                String url = urlStyleMatcher.group(1);
                                if (!new UrlValidator(customSchemes).isValid(url)) {
                                    ret.invalidTags.add(tag + " " + attr + " " + styleValue);
                                    continue;
                                }
                            }

                            cleanStyle = cleanStyle + styleName + ":" + encode(styleValue) + ";";

                        }
                        val = cleanStyle;

                    } else if (attr.startsWith("on")) { // skip all javascript events
                        ret.invalidTags.add(tag + " " + attr + " " + val);
                        continue;

                    } else { // by default encode all properies
                        val = encode(val);
                    }

                    cleanToken = cleanToken + " " + attr + "=\"" + val + "\"";
                }
                cleanToken = cleanToken + ">";

                isAcceptedToken = true;

                // for <img> and <a>
                if (tag.matches("a|img|embed") && !foundURL) {
                    isAcceptedToken = false;
                    cleanToken = "";
                }

                token = cleanToken;

                // push the tag if require closure and it is accepted (otherwirse is encoded)
                if (isAcceptedToken && !(standAloneTags.matcher(tag).find() || selfClosed.matcher(tag).find()))
                    openTags.push(tag);

                //   UNKNOWN TAG
            } else {
                ret.invalidTags.add(token);
                ret.val = ret.val + token;
                continue;

            }

            //   CLOSE TAG </tag>
        } else if (endMatcher.find()) {
            String tag = endMatcher.group(1).toLowerCase();

            //is self closing
            if (selfClosed.matcher(tag).find()) {
                ret.invalidTags.add(token);
                continue;
            }
            if (forbiddenTags.matcher(tag).find()) {
                ret.invalidTags.add("/" + tag);
                continue;
            }
            if (!allowedTags.matcher(tag).find()) {
                ret.invalidTags.add(token);
                ret.val = ret.val + token;
                continue;
            } else {

                String cleanToken = "";

                // check tag position in the stack
                int pos = openTags.search(tag);
                // if found on top ok
                for (int i = 1; i <= pos; i++) {
                    //pop all elements before tag and close it
                    String poppedTag = openTags.pop();
                    cleanToken = cleanToken + "</" + poppedTag + ">";
                    isAcceptedToken = true;
                }

                token = cleanToken;
            }

        }

        ret.val = ret.val + token;

        if (isAcceptedToken) {
            ret.html = ret.html + token;
            //ret.text = ret.text + " ";
        } else {
            String sanToken = htmlEncodeApexesAndTags(token);
            ret.html = ret.html + sanToken;
            ret.text = ret.text + htmlEncodeApexesAndTags(removeLineFeed(token));
        }

    }

    // must close remaining tags
    while (openTags.size() > 0) {
        //pop all elements before tag and close it
        String poppedTag = openTags.pop();
        ret.html = ret.html + "</" + poppedTag + ">";
        ret.val = ret.val + "</" + poppedTag + ">";
    }

    //set boolean value
    ret.isValid = ret.invalidTags.size() == 0;

    return ret;
}

From source file:org.apache.roller.weblogger.util.HTMLSanitizer.java

public static SanitizeResult sanitizer(String html, Pattern allowedTags, Pattern forbiddenTags) {
    SanitizeResult ret = new SanitizeResult();
    Stack<String> openTags = new Stack();

    List<String> tokens = tokenize(html);

    // -------------------   LOOP for every token --------------------------
    for (String token : tokens) {
        boolean isAcceptedToken = false;

        Matcher startMatcher = tagStartPattern.matcher(token);
        Matcher endMatcher = tagClosePattern.matcher(token);

        //--------------------------------------------------------------------------------  COMMENT    <!-- ......... -->
        if (commentPattern.matcher(token).find()) {
            ret.val = ret.val + token + (token.endsWith("-->") ? "" : "-->");
            ret.invalidTags.add(token + (token.endsWith("-->") ? "" : "-->"));
            continue;

            //--------------------------------------------------------------------------------  OPEN TAG    <tag .........>
        } else if (startMatcher.find()) {

            //tag name extraction
            String tag = startMatcher.group(1).toLowerCase();

            //-----------------------------------------------------  FORBIDDEN TAG   <script .........>
            if (forbiddenTags.matcher(tag).find()) {
                ret.invalidTags.add("<" + tag + ">");
                continue;

                // --------------------------------------------------  WELL KNOWN TAG
            } else if (allowedTags.matcher(tag).find()) {

                String cleanToken = "<" + tag;
                String tokenBody = startMatcher.group(2);

                //first test table consistency
                //table tbody tfoot thead th tr td
                if ("thead".equals(tag) || "tbody".equals(tag) || "tfoot".equals(tag) || "tr".equals(tag)) {
                    if (openTags.search("table") < 1) {
                        ret.invalidTags.add("<" + tag + ">");
                        continue;
                    }/*from w w  w.  ja  v  a 2  s . co  m*/
                } else if ("td".equals(tag) || "th".equals(tag)) {
                    if (openTags.search("tr") < 1) {
                        ret.invalidTags.add("<" + tag + ">");
                        continue;
                    }
                }

                // then test properties
                Matcher attributes = attributesPattern.matcher(tokenBody);

                boolean foundURL = false; // URL flag
                while (attributes.find()) {

                    String attr = attributes.group(1).toLowerCase();
                    String val = attributes.group(2);

                    // we will accept href in case of <A>
                    if ("a".equals(tag) && "href".equals(attr)) { // <a href="......">
                        String[] customSchemes = { "http", "https" };
                        if (new UrlValidator(customSchemes).isValid(val)) {
                            foundURL = true;
                        } else {
                            // may be it is a mailto?
                            //  case <a href="mailto:pippo@pippo.com?subject=...."
                            if (val.toLowerCase().startsWith("mailto:") && val.indexOf('@') >= 0) {
                                String val1 = "http://www." + val.substring(val.indexOf('@') + 1);
                                if (new UrlValidator(customSchemes).isValid(val1)) {
                                    foundURL = true;
                                } else {
                                    ret.invalidTags.add(attr + " " + val);
                                    val = "";
                                }
                            } else {
                                ret.invalidTags.add(attr + " " + val);
                                val = "";
                            }
                        }

                    } else if (tag.matches("img|embed") && "src".equals(attr)) { // <img src="......">
                        String[] customSchemes = { "http", "https" };
                        if (new UrlValidator(customSchemes).isValid(val)) {
                            foundURL = true;
                        } else {
                            ret.invalidTags.add(attr + " " + val);
                            val = "";
                        }

                    } else if ("href".equals(attr) || "src".equals(attr)) { // <tag src/href="......">   skipped
                        ret.invalidTags.add(tag + " " + attr + " " + val);
                        continue;

                    } else if (attr.matches("width|height")) { // <tag width/height="......">
                        if (!val.toLowerCase().matches("\\d+%|\\d+$")) { // test numeric values
                            ret.invalidTags.add(tag + " " + attr + " " + val);
                            continue;
                        }

                    } else if ("style".equals(attr)) { // <tag style="......">

                        // then test properties
                        Matcher styles = stylePattern.matcher(val);
                        String cleanStyle = "";

                        while (styles.find()) {
                            String styleName = styles.group(1).toLowerCase();
                            String styleValue = styles.group(2);

                            // suppress invalid styles values
                            if (forbiddenStylePattern.matcher(styleValue).find()) {
                                ret.invalidTags.add(tag + " " + attr + " " + styleValue);
                                continue;
                            }

                            // check if valid url
                            Matcher urlStyleMatcher = urlStylePattern.matcher(styleValue);
                            if (urlStyleMatcher.find()) {
                                String[] customSchemes = { "http", "https" };
                                String url = urlStyleMatcher.group(1);
                                if (!new UrlValidator(customSchemes).isValid(url)) {
                                    ret.invalidTags.add(tag + " " + attr + " " + styleValue);
                                    continue;
                                }
                            }

                            cleanStyle = cleanStyle + styleName + ":" + encode(styleValue) + ";";

                        }
                        val = cleanStyle;

                    } else if (attr.startsWith("on")) { // skip all javascript events
                        ret.invalidTags.add(tag + " " + attr + " " + val);
                        continue;

                    } else { // by default encode all properies
                        val = encode(val);
                    }

                    cleanToken = cleanToken + " " + attr + "=\"" + val + "\"";
                }
                cleanToken = cleanToken + ">";

                isAcceptedToken = true;

                // for <img> and <a>
                if (tag.matches("a|img|embed") && !foundURL) {
                    isAcceptedToken = false;
                    cleanToken = "";
                }

                token = cleanToken;

                // push the tag if require closure and it is accepted (otherwirse is encoded)
                if (isAcceptedToken
                        && !(standAloneTags.matcher(tag).find() || selfClosed.matcher(tag).find())) {
                    openTags.push(tag);
                }

                // --------------------------------------------------------------------------------  UNKNOWN TAG
            } else {
                ret.invalidTags.add(token);
                ret.val = ret.val + token;
                continue;

            }

            // --------------------------------------------------------------------------------  CLOSE TAG </tag>
        } else if (endMatcher.find()) {
            String tag = endMatcher.group(1).toLowerCase();

            //is self closing
            if (selfClosed.matcher(tag).find()) {
                ret.invalidTags.add(token);
                continue;
            }
            if (forbiddenTags.matcher(tag).find()) {
                ret.invalidTags.add("/" + tag);
                continue;
            }
            if (!allowedTags.matcher(tag).find()) {
                ret.invalidTags.add(token);
                ret.val = ret.val + token;
                continue;
            } else {

                String cleanToken = "";

                // check tag position in the stack
                int pos = openTags.search(tag);
                // if found on top ok
                for (int i = 1; i <= pos; i++) {
                    //pop all elements before tag and close it
                    String poppedTag = openTags.pop();
                    cleanToken = cleanToken + "</" + poppedTag + ">";
                    isAcceptedToken = true;
                }

                token = cleanToken;
            }

        }

        ret.val = ret.val + token;

        if (isAcceptedToken) {
            ret.html = ret.html + token;
            //ret.text = ret.text + " ";
        } else {
            String sanToken = htmlEncodeApexesAndTags(token);
            ret.html = ret.html + sanToken;
            ret.text = ret.text + htmlEncodeApexesAndTags(removeLineFeed(token));
        }

    }

    // must close remaining tags
    while (openTags.size() > 0) {
        //pop all elements before tag and close it
        String poppedTag = openTags.pop();
        ret.html = ret.html + "</" + poppedTag + ">";
        ret.val = ret.val + "</" + poppedTag + ">";
    }

    //set boolean value
    ret.isValid = ret.invalidTags.size() == 0;

    return ret;
}

From source file:ecar.util.HtmlSanitizer.java

public static SanitizeResult sanitizer(String html, Pattern allowedTags, Pattern forbiddenTags) {
    SanitizeResult ret = new SanitizeResult();
    Stack<String> openTags = new Stack();

    List<String> tokens = tokenize(html);

    // ------------------- LOOP for every token --------------------------
    for (String token : tokens) {
        boolean isAcceptedToken = false;

        Matcher startMatcher = tagStartPattern.matcher(token);
        Matcher endMatcher = tagClosePattern.matcher(token);

        // --------------------------------------------------------------------------------
        // COMMENT <!-- ......... -->
        if (commentPattern.matcher(token).find()) {
            ret.val = ret.val + token + (token.endsWith("-->") ? "" : "-->");
            ret.invalidTags.add(token + (token.endsWith("-->") ? "" : "-->"));
            continue;

            // --------------------------------------------------------------------------------
            // OPEN TAG <tag .........>
        } else if (startMatcher.find()) {

            // tag name extraction
            String tag = startMatcher.group(1).toLowerCase();

            // -----------------------------------------------------
            // FORBIDDEN TAG <script .........>
            if (forbiddenTags.matcher(tag).find()) {
                ret.invalidTags.add("<" + tag + ">");
                continue;

                // -------------------------------------------------- WELL
                // KNOWN TAG
            } else if (allowedTags.matcher(tag).find()) {

                String cleanToken = "<" + tag;
                String tokenBody = startMatcher.group(2);

                // first test table consistency
                // table tbody tfoot thead th tr td
                if ("thead".equals(tag) || "tbody".equals(tag) || "tfoot".equals(tag) || "tr".equals(tag)) {
                    if (openTags.search("table") < 1) {
                        ret.invalidTags.add("<" + tag + ">");
                        continue;
                    }//from   w w  w  .j av a2s  .  c  o m
                } else if ("td".equals(tag) || "th".equals(tag)) {
                    if (openTags.search("tr") < 1) {
                        ret.invalidTags.add("<" + tag + ">");
                        continue;
                    }
                }

                // then test properties
                Matcher attributes = attributesPattern.matcher(tokenBody);

                boolean foundURL = false; // URL flag
                while (attributes.find()) {

                    String attr = attributes.group(1).toLowerCase();
                    String val = attributes.group(2);

                    // we will accept href in case of <A>
                    if ("a".equals(tag) && "href".equals(attr)) { // <a
                        // href="......">
                        String[] customSchemes = { "http", "https" };
                        if (new UrlValidator(customSchemes).isValid(val)) {
                            foundURL = true;
                        } else {
                            // may be it is a mailto?
                            // case <a
                            // href="mailto:pippo@pippo.com?subject=...."
                            if (val.toLowerCase().startsWith("mailto:") && val.indexOf("@") >= 0) {
                                String val1 = "http://www." + val.substring(val.indexOf("@") + 1);
                                if (new UrlValidator(customSchemes).isValid(val1)) {
                                    foundURL = true;
                                } else {
                                    ret.invalidTags.add(attr + " " + val);
                                    val = "";
                                }
                            } else {
                                ret.invalidTags.add(attr + " " + val);
                                val = "";
                            }
                        }

                    } else if (tag.matches("img|embed") && "src".equals(attr)) { // <img src="......">
                        String[] customSchemes = { "http", "https" };
                        if (new UrlValidator(customSchemes).isValid(val)) {
                            foundURL = true;
                        } else {
                            ret.invalidTags.add(attr + " " + val);
                            val = "";
                        }

                    } else if ("href".equals(attr) || "src".equals(attr)) { // <tag
                        // src/href="......">
                        // skipped
                        ret.invalidTags.add(tag + " " + attr + " " + val);
                        continue;

                    } else if (attr.matches("width|height")) { // <tag
                        // width/height="......">
                        if (!val.toLowerCase().matches("\\d+%|\\d+$")) { // test
                            // numeric
                            // values
                            ret.invalidTags.add(tag + " " + attr + " " + val);
                            continue;
                        }

                    } else if ("style".equals(attr)) { // <tag
                        // style="......">

                        // then test properties
                        Matcher styles = stylePattern.matcher(val);
                        String cleanStyle = "";

                        while (styles.find()) {
                            String styleName = styles.group(1).toLowerCase();
                            String styleValue = styles.group(2);

                            // suppress invalid styles values
                            if (forbiddenStylePattern.matcher(styleValue).find()) {
                                ret.invalidTags.add(tag + " " + attr + " " + styleValue);
                                continue;
                            }

                            // check if valid url
                            Matcher urlStyleMatcher = urlStylePattern.matcher(styleValue);
                            if (urlStyleMatcher.find()) {
                                String[] customSchemes = { "http", "https" };
                                String url = urlStyleMatcher.group(1);
                                if (!new UrlValidator(customSchemes).isValid(url)) {
                                    ret.invalidTags.add(tag + " " + attr + " " + styleValue);
                                    continue;
                                }
                            }

                            cleanStyle = cleanStyle + styleName + ":" + encode(styleValue) + ";";

                        }
                        val = cleanStyle;

                    } else if (attr.startsWith("on")) { // skip all
                        // javascript events
                        ret.invalidTags.add(tag + " " + attr + " " + val);
                        continue;

                    } else { // by default encode all properies
                        val = encode(val);
                    }

                    cleanToken = cleanToken + " " + attr + "=\"" + val + "\"";
                }
                cleanToken = cleanToken + ">";

                isAcceptedToken = true;

                // for <img> and <a>
                if (tag.matches("a|img|embed") && !foundURL) {
                    isAcceptedToken = false;
                    cleanToken = "";
                }

                token = cleanToken;

                // push the tag if require closure and it is accepted
                // (otherwirse is encoded)
                if (isAcceptedToken && !(standAloneTags.matcher(tag).find() || selfClosed.matcher(tag).find()))
                    openTags.push(tag);

                // --------------------------------------------------------------------------------
                // UNKNOWN TAG
            } else {
                ret.invalidTags.add(token);
                ret.val = ret.val + token;
                continue;

            }

            // --------------------------------------------------------------------------------
            // CLOSE TAG </tag>
        } else if (endMatcher.find()) {
            String tag = endMatcher.group(1).toLowerCase();

            // is self closing
            if (selfClosed.matcher(tag).find()) {
                ret.invalidTags.add(token);
                continue;
            }
            if (forbiddenTags.matcher(tag).find()) {
                ret.invalidTags.add("/" + tag);
                continue;
            }
            if (!allowedTags.matcher(tag).find()) {
                ret.invalidTags.add(token);
                ret.val = ret.val + token;
                continue;
            } else {

                String cleanToken = "";

                // check tag position in the stack
                int pos = openTags.search(tag);
                // if found on top ok
                for (int i = 1; i <= pos; i++) {
                    // pop all elements before tag and close it
                    String poppedTag = openTags.pop();
                    cleanToken = cleanToken + "</" + poppedTag + ">";
                    isAcceptedToken = true;
                }

                token = cleanToken;
            }

        }

        ret.val = ret.val + token;

        if (isAcceptedToken) {
            ret.html = ret.html + token;
            // ret.text = ret.text + " ";
        } else {
            String sanToken = htmlEncodeApexesAndTags(token);
            ret.html = ret.html + sanToken;
            ret.text = ret.text + htmlEncodeApexesAndTags(removeLineFeed(token));
        }

    }

    // must close remaining tags
    while (openTags.size() > 0) {
        // pop all elements before tag and close it
        String poppedTag = openTags.pop();
        ret.html = ret.html + "</" + poppedTag + ">";
        ret.val = ret.val + "</" + poppedTag + ">";
    }

    // set boolean value
    ret.isValid = ret.invalidTags.size() == 0;

    return ret;
}