Package org.objectweb.celtix.bus.configuration.spring

Source Code of org.objectweb.celtix.bus.configuration.spring.BeanName

package org.objectweb.celtix.bus.configuration.spring;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

import org.objectweb.celtix.configuration.Configuration;

class BeanName {
   
    static final char LOOSE_BINDING = '*';
    static final char TIGHT_BINDING = '.';   
    static final char NAMESPACE_URI_OPEN = '{';
    static final char NAMESPACE_URI_CLOSE = '}';
   
    static final String ANY_COMPONENT = "?";
   
    String name;
    String normalisedName;
    ComponentIterator iterator;   
   
    BeanName(String n) {
        this(n, false);
    }
   
    BeanName(String n, boolean doNormalise) {
        name = n;
        normalisedName = null;
        if (doNormalise) {
            normalise();
        }
    }  
   
    BeanName(Configuration conf) {
        StringBuffer buf = new StringBuffer();
        Configuration c = conf;
        while (null != c) {
            if (buf.length() > 0) {
                buf.insert(0, TIGHT_BINDING);
            }
            buf.insert(0, c.getId().toString());
            c = c.getParent();
        }
        name = buf.toString();
        normalisedName = name;
    }
   
    public String toString() {
        return name;
   
   
    int compareTo(BeanName other, String component) {

        int result = 0;
       
        // An entry that contains a matching component (whether name or  "?")
        // takes precedence over entries that elide the level (that is, entries
        // that match the level in a loose binding).
       
        char lb = iterator.lastBinding();
        char olb = other.iterator.lastBinding();
      
       
        if (matchCurrentComponentName(component)) {
            if (!other.matchCurrentComponentName(component) && LOOSE_BINDING == olb) {
                result = -1;
            }
        } else if (other.matchCurrentComponentName(component) && LOOSE_BINDING == lb) {
            return 1;          
        }
       
        if (0 != result) {
            return result;
        }
       
        // An entry with a matching name takes precedence over
        // entries that match using "?".

        String c = iterator.current;
        String oc = other.iterator.current;
       
        if (ANY_COMPONENT.equals(c)) {
            if (!ANY_COMPONENT.equals(oc)) {
                result = 1;
            }
        } else {
            if (ANY_COMPONENT.equals(oc)) {
                result = -1;
            }
        }
        if (0 != result) {
            return result;
        }
       
        // An entry preceded by a tight binding takes precedence
        // over entries preceded by a loose binding.  
       
        if (isTightBinding(lb) && isLooseBinding(olb)) {
            result = -1;
        } else if (isLooseBinding(lb) && isTightBinding(olb)) {
            result = 1;
        }
        return result;
    }

    String getName() {
        return name;
    }
   
    String getNormalisedName() {
        return normalisedName;
    }
   
    BeanName findBestMatch(List<BeanName> candidateBeans) {
        List<BeanName> candidates = new ArrayList<BeanName>(candidateBeans);
       
        for (BeanName bn : candidates) {
            if (name.equals(bn.name)) {
                return bn;
            }
            bn.normalise();
            bn.reset();
            if (bn.iterator.hasNext()) {
                bn.iterator.next();
            }
        }
       
        normalise();
        reset();
       
        while (iterator.hasNext() && candidates.size() > 0) {
           
            iterator.next();           
           
            // at each level:
           
            // remove the non matching candidates
           
            for (int i = candidates.size() - 1; i >= 0; i--) {
                BeanName candidate = candidates.get(i);
                if (!match(candidate)) {
                    candidates.remove(i);
                }
            }
           
            // sort the remainder - using a comparator specific to the current level

            Comparator<BeanName> comparator = new Comparator<BeanName>() {
                public int compare(BeanName o1, BeanName o2) {
                    return o1.compareTo(o2, iterator.current);
                }  
            };
            Collections.sort(candidates, comparator);
           
            // keep only the ties
           
            int i = 1;
            while (i < candidates.size()) {
                int diff = candidates.get(0).compareTo(candidates.get(i),
                                                       iterator.current);                   
                if (diff < 0) {
                    break;
                }
                i++;
            }
            while (i < candidates.size()) {
                candidates.remove(candidates.size() - 1);     
            }
           
           
            // advance remaining candidate iterators where necessary,
            // pruning the list if necessary
           
            ListIterator<BeanName> it = candidates.listIterator();
            BeanName candidate = it.hasNext() ? it.next() : null;
            while (null != candidate) {
                BeanName nextCandidate = it.hasNext() ? it.next() : null;
                char lb = candidate.iterator.lastBinding();
                if (0 == lb || isTightBinding(lb)) {
                    if (candidate.iterator.hasNext()) {
                        candidate.iterator.next();
                    } else if (iterator.hasNext()) {
                        candidates.remove(candidate);
                    }
                } else if (matchCurrentComponentName(candidate)) {
                    assert isLooseBinding(lb);
                    if (candidate.iterator.hasNext()) {
                        candidate.iterator.next();
                    } else if (iterator.hasNext()) {
                        candidates.remove(candidate);
                    }
                }
                candidate = nextCandidate;
            }
        }
        if (candidates.size() > 0) {
            return candidates.get(0);
        }
        return null;
    }
   
   
    boolean match(BeanName other) {
        char olb = other.iterator.lastBinding();
        if (isLooseBinding(olb)) {
            return true;
        } else {
            return matchCurrentComponentName(other);
        }
    }
   
    boolean matchCurrentComponentName(BeanName other) {
        return iterator.current.equals(other.iterator.current)
            || ANY_COMPONENT.equals(other.iterator.current);
    }
   
    boolean matchCurrentComponentName(String component) {
        return component.equals(iterator.current)
            || ANY_COMPONENT.equals(iterator.current);
    }
   
    /**
     * Replace contiguous sequences of two or more binding characters by 
     * a single tight binding if the sequence contains only tight binding characters,
     * or by a loose binding character otherwise.
     * @param beanName
     * @return
     */
   
    final void normalise() {
        if (null != normalisedName) {
            return;
        }
        if (null == name || name.length() < 2) {
            normalisedName = name;
            return;
        }
        StringBuffer buf = new StringBuffer();
       
        int i = 0;
        int from = 0;       
        while (i < name.length()) {
            boolean inNamespaceURI = false;
            from = i;
            if (isBinding(name.charAt(i))) {
                while (i < name.length() && isBinding(name.charAt(i))) {
                    i++;
                }
                if (i - from > 1) { 
                    int pos = name.indexOf(LOOSE_BINDING, from);
                    if (pos >= 0 && pos <= i) {
                        buf.append(LOOSE_BINDING);
                       
                    } else {
                        buf.append(TIGHT_BINDING);
                    }
                } else {
                    buf.append(name.charAt(from));
                }
               
            } else {
                do {
                    buf.append(name.charAt(i));
                    if (NAMESPACE_URI_OPEN == name.charAt(i) && !inNamespaceURI) {
                        inNamespaceURI = true;
                    } else if (NAMESPACE_URI_CLOSE == name.charAt(i) && inNamespaceURI) {
                        inNamespaceURI = false;
                    }
                    i++;
                } while (i < name.length() && (!isBinding(name.charAt(i)) || inNamespaceURI));
            }
        }
      
        normalisedName = buf.toString();
    }
   
    final void reset() {
        iterator = new ComponentIterator();
    }
   
    final ComponentIterator getIterator() {
        if (null == iterator) {
            iterator = new ComponentIterator();
        }
        return iterator;
    }
   
   
    static boolean isBinding(char c) {
        return isTightBinding(c) || isLooseBinding(c);
    }
   
    static boolean isTightBinding(char c) {
        return TIGHT_BINDING == c;
    }
   
    static boolean isLooseBinding(char c) {
        return LOOSE_BINDING == c;
    }
   
    final class ComponentIterator implements Iterator {
        int componentStart = -1;
        int componentEnd = -1;
        String current;
       
        public boolean hasNext() {
            if (null == normalisedName) {
                return false;
            }
            return componentEnd + 1 < normalisedName.length();
        }

        public Object next() {
            if (-1 == componentStart && -1 == componentEnd && isBinding(normalisedName.charAt(0))) {
                componentStart++;
                componentEnd++;
            }
            componentStart = componentEnd + 1;
            componentEnd = componentStart + 1;
            boolean inNamespaceURI = false;
            if (componentStart < normalisedName.length()
                && NAMESPACE_URI_OPEN == normalisedName.charAt(componentStart)) {
                inNamespaceURI = true;
            }
           
            while (componentEnd < normalisedName.length()) {
                if (NAMESPACE_URI_OPEN == normalisedName.charAt(componentEnd) && !inNamespaceURI) {
                    inNamespaceURI = true;
                } else if (NAMESPACE_URI_CLOSE == normalisedName.charAt(componentEnd) && inNamespaceURI) {
                    inNamespaceURI = false;
                }
                if (!inNamespaceURI && isBinding(normalisedName.charAt(componentEnd)))
                {
                    break;
                }
                componentEnd++;
            }
            /*
            while (componentEnd < normalisedName.length()
                && !isBinding(normalisedName.charAt(componentEnd))) {
                componentEnd++;
            }
            */
            current = normalisedName.substring(componentStart, componentEnd);
            return current;
        }

        public void remove() {
            // TODO Auto-generated method stub      
        }
       
        char lastBinding() {
            if (componentStart > 0) {
                return normalisedName.charAt(componentStart - 1);
            }
            return 0;
        }
       
       
    }
}
TOP

Related Classes of org.objectweb.celtix.bus.configuration.spring.BeanName

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