NameImpl.java :  » 6.0-JDK-Core » naming » javax » naming » Java Open Source

Java Open Source » 6.0 JDK Core » naming 
naming » javax » naming » NameImpl.java
/*
 * Copyright 1999-2002 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package javax.naming;

import java.util.Vector;
import java.util.Enumeration;
import java.util.Properties;
import java.util.NoSuchElementException;

/**
  * The implementation class for CompoundName and CompositeName.
  * This class is package private.
  *
  * @author Rosanna Lee
  * @author Scott Seligman
  * @author Aravindan Ranganathan
  * @version 1.16 07/05/05
  * @since 1.3
  */

class NameImpl {
    private static final byte LEFT_TO_RIGHT = 1;
    private static final byte RIGHT_TO_LEFT = 2;
    private static final byte FLAT = 0;

    private Vector components;

    private byte syntaxDirection = LEFT_TO_RIGHT;
    private String syntaxSeparator = "/";
    private String syntaxSeparator2 = null;
    private boolean syntaxCaseInsensitive = false;
    private boolean syntaxTrimBlanks = false;
    private String syntaxEscape = "\\";
    private String syntaxBeginQuote1 = "\"";
    private String syntaxEndQuote1 = "\"";
    private String syntaxBeginQuote2 = "'";
    private String syntaxEndQuote2 = "'";
    private String syntaxAvaSeparator = null;
    private String syntaxTypevalSeparator = null;

    // escapingStyle gives the method used at creation time for
    // quoting or escaping characters in the name.  It is set to the
    // first style of quote or escape encountered if and when the name
    // is parsed.
    private static final int STYLE_NONE = 0;
    private static final int STYLE_QUOTE1 = 1;
    private static final int STYLE_QUOTE2 = 2;
    private static final int STYLE_ESCAPE = 3;
    private int escapingStyle = STYLE_NONE;

    // Returns true if "match" is not null, and n contains "match" at
    // position i.
    private final boolean isA(String n, int i, String match) {
  return (match != null && n.startsWith(match, i));
    }

    private final boolean isMeta(String n, int i) {
  return (isA(n, i, syntaxEscape) ||
    isA(n, i, syntaxBeginQuote1) ||
    isA(n, i, syntaxBeginQuote2) ||
    isSeparator(n, i));
    }

    private final boolean isSeparator(String n, int i) {
  return (isA(n, i, syntaxSeparator) ||
    isA(n, i, syntaxSeparator2));
    }

    private final int skipSeparator(String name, int i) {
  if (isA(name, i, syntaxSeparator)) {
      i += syntaxSeparator.length();
  } else if (isA(name, i, syntaxSeparator2)) {
      i += syntaxSeparator2.length();
  }
  return (i);
    }

    private final int extractComp(String name, int i, int len, Vector comps) 
    throws InvalidNameException {
  String beginQuote;
  String endQuote;
  boolean start = true;
  boolean one = false;
  StringBuffer answer = new StringBuffer(len);

  while (i < len) {
      // handle quoted strings
      if (start && ((one = isA(name, i, syntaxBeginQuote1)) ||
        isA(name, i, syntaxBeginQuote2))) {

    // record choice of quote chars being used
    beginQuote = one ? syntaxBeginQuote1 : syntaxBeginQuote2;
    endQuote = one ? syntaxEndQuote1 : syntaxEndQuote2;
    if (escapingStyle == STYLE_NONE) {
        escapingStyle = one ? STYLE_QUOTE1 : STYLE_QUOTE2;
    }

    // consume string until matching quote
    for (i += beginQuote.length();
         ((i < len) && !name.startsWith(endQuote, i));
         i++) {
        // skip escape character if it is escaping ending quote
        // otherwise leave as is.
        if (isA(name, i, syntaxEscape) &&
      isA(name, i + syntaxEscape.length(), endQuote)) {
      i += syntaxEscape.length();
        }
        answer.append(name.charAt(i));  // copy char
    }

    // no ending quote found
    if (i >= len)
        throw 
      new InvalidNameException(name + ": no close quote");
//      new Exception("no close quote");

    i += endQuote.length();

    // verify that end-quote occurs at separator or end of string
    if (i == len || isSeparator(name, i)) {
        break;
    }
//    throw (new Exception(
    throw (new InvalidNameException(name +
        ": close quote appears before end of component"));

      } else if (isSeparator(name, i)) {
    break;

      } else if (isA(name, i, syntaxEscape)) {
    if (isMeta(name, i + syntaxEscape.length())) {
        // if escape precedes meta, consume escape and let
        // meta through
        i += syntaxEscape.length();
        if (escapingStyle == STYLE_NONE) {
      escapingStyle = STYLE_ESCAPE;
        }
    } else if (i + syntaxEscape.length() >= len) {
        throw (new InvalidNameException(name +
      ": unescaped " + syntaxEscape + " at end of component"));
    }
      } else if (isA(name, i, syntaxTypevalSeparator) &&
  ((one = isA(name, i+syntaxTypevalSeparator.length(), syntaxBeginQuote1)) ||
      isA(name, i+syntaxTypevalSeparator.length(), syntaxBeginQuote2))) {
    // Handle quote occurring after typeval separator
    beginQuote = one ? syntaxBeginQuote1 : syntaxBeginQuote2;
    endQuote = one ? syntaxEndQuote1 : syntaxEndQuote2;

    i += syntaxTypevalSeparator.length();
    answer.append(syntaxTypevalSeparator+beginQuote); // add back
    
    // consume string until matching quote
    for (i += beginQuote.length();
         ((i < len) && !name.startsWith(endQuote, i));
         i++) {
        // skip escape character if it is escaping ending quote
        // otherwise leave as is.
        if (isA(name, i, syntaxEscape) &&
      isA(name, i + syntaxEscape.length(), endQuote)) {
      i += syntaxEscape.length();
        }
        answer.append(name.charAt(i));  // copy char
    }

    // no ending quote found
    if (i >= len)
        throw 
      new InvalidNameException(name + ": typeval no close quote");

    i += endQuote.length();
    answer.append(endQuote); // add back

    // verify that end-quote occurs at separator or end of string
    if (i == len || isSeparator(name, i)) {
        break;
    }
    throw (new InvalidNameException(name.substring(i) +
        ": typeval close quote appears before end of component"));
      }

      answer.append(name.charAt(i++));
      start = false;
  }

  if (syntaxDirection == RIGHT_TO_LEFT)
      comps.insertElementAt(answer.toString(), 0);
  else
      comps.addElement(answer.toString());
  return i;
    }

    private static boolean getBoolean(Properties p, String name) {
  return toBoolean(p.getProperty(name));
    }

    private static boolean toBoolean(String name) { 
  return ((name != null) && name.toLowerCase().equals("true"));
    }

    private final void recordNamingConvention(Properties p) {
  String syntaxDirectionStr = 
      p.getProperty("jndi.syntax.direction", "flat");
  if (syntaxDirectionStr.equals("left_to_right")) {
      syntaxDirection = LEFT_TO_RIGHT;
  } else if (syntaxDirectionStr.equals("right_to_left")) {
      syntaxDirection = RIGHT_TO_LEFT;
  } else if (syntaxDirectionStr.equals("flat")) {
      syntaxDirection = FLAT;
  } else {
      throw new IllegalArgumentException(syntaxDirectionStr +
    "is not a valid value for the jndi.syntax.direction property");
  }  

  if (syntaxDirection != FLAT) {
      syntaxSeparator = p.getProperty("jndi.syntax.separator");
      syntaxSeparator2 = p.getProperty("jndi.syntax.separator2");
      if (syntaxSeparator == null) {
    throw new IllegalArgumentException(
        "jndi.syntax.separator property required for non-flat syntax");
      }
  } else {
      syntaxSeparator = null;
  }
  syntaxEscape = p.getProperty("jndi.syntax.escape");

  syntaxCaseInsensitive = getBoolean(p, "jndi.syntax.ignorecase");
  syntaxTrimBlanks = getBoolean(p, "jndi.syntax.trimblanks");

  syntaxBeginQuote1 = p.getProperty("jndi.syntax.beginquote");
  syntaxEndQuote1 = p.getProperty("jndi.syntax.endquote");
  if (syntaxEndQuote1 == null && syntaxBeginQuote1 != null)
      syntaxEndQuote1 = syntaxBeginQuote1;
  else if (syntaxBeginQuote1 == null && syntaxEndQuote1 != null)
      syntaxBeginQuote1 = syntaxEndQuote1;
  syntaxBeginQuote2 = p.getProperty("jndi.syntax.beginquote2");
  syntaxEndQuote2 = p.getProperty("jndi.syntax.endquote2");
  if (syntaxEndQuote2 == null && syntaxBeginQuote2 != null)
      syntaxEndQuote2 = syntaxBeginQuote2;
  else if (syntaxBeginQuote2 == null && syntaxEndQuote2 != null)
      syntaxBeginQuote2 = syntaxEndQuote2;

  syntaxAvaSeparator = p.getProperty("jndi.syntax.separator.ava");
  syntaxTypevalSeparator = 
      p.getProperty("jndi.syntax.separator.typeval");
    }

    NameImpl(Properties syntax) {
  if (syntax != null) {
      recordNamingConvention(syntax);
  }
  components = new Vector();
    }

    NameImpl(Properties syntax, String n) throws InvalidNameException {
  this(syntax);

  boolean rToL = (syntaxDirection == RIGHT_TO_LEFT);
  boolean compsAllEmpty = true;
  int len = n.length();

  for (int i = 0; i < len; ) {
      i = extractComp(n, i, len, components);

      String comp = rToL
    ? (String)components.firstElement()
    : (String)components.lastElement();
      if (comp.length() >= 1) {
    compsAllEmpty = false;
      }

      if (i < len) {
    i = skipSeparator(n, i);
    if ((i == len) && !compsAllEmpty) {
        // Trailing separator found.  Add an empty component.
        if (rToL) {
      components.insertElementAt("", 0);
        } else {
      components.addElement("");
        }
    }
      }
  }
    }

    NameImpl(Properties syntax, Enumeration comps) {
  this(syntax);

  // %% comps could shrink in the middle.
  while (comps.hasMoreElements())
      components.addElement(comps.nextElement());
    }
/*
    // Determines whether this component needs any escaping.
    private final boolean escapingNeeded(String comp) {
  int len = comp.length();
  for (int i = 0; i < len; i++) {
      if (i == 0) {
    if (isA(comp, 0, syntaxBeginQuote1) ||
        isA(comp, 0, syntaxBeginQuote2)) {
        return (true);
    }
      }
      if (isSeparator(comp, i)) {
    return (true);
      }
      if (isA(comp, i, syntaxEscape)) {
    i += syntaxEscape.length();
    if (i >= len || isMeta(comp, i)) {
        return (true);
    }
      }
  }
  return (false);
    }
*/
    private final String stringifyComp(String comp) {
  int len = comp.length();
  boolean escapeSeparator = false, escapeSeparator2 = false;
  String beginQuote = null, endQuote = null;
  StringBuffer strbuf = new StringBuffer(len);

  // determine whether there are any separators; if so escape
  // or quote them
  if (syntaxSeparator != null &&
      comp.indexOf(syntaxSeparator) >= 0) {
      if (syntaxBeginQuote1 != null) {
    beginQuote = syntaxBeginQuote1;
    endQuote = syntaxEndQuote1;
      } else if (syntaxBeginQuote2 != null) {
    beginQuote = syntaxBeginQuote2;
    endQuote = syntaxEndQuote2;
      } else if (syntaxEscape != null)
    escapeSeparator = true;
  }
  if (syntaxSeparator2 != null &&
      comp.indexOf(syntaxSeparator2) >= 0) {
      if (syntaxBeginQuote1 != null) {
    if (beginQuote == null) {
        beginQuote = syntaxBeginQuote1;
        endQuote = syntaxEndQuote1;
    }
      } else if (syntaxBeginQuote2 != null) {
    if (beginQuote == null) {
        beginQuote = syntaxBeginQuote2;
        endQuote = syntaxEndQuote2;
    }
      } else if (syntaxEscape != null)
    escapeSeparator2 = true;
  }

  // if quoting component, 
  if (beginQuote != null) {

      // start string off with opening quote
      strbuf = strbuf.append(beginQuote);

      // component is being quoted, so we only need to worry about
      // escaping end quotes that occur in component
      for (int i = 0; i < len; ) {
    if (comp.startsWith(endQuote, i)) {
        // end-quotes must be escaped when inside a quoted string
        strbuf.append(syntaxEscape).append(endQuote);
        i += endQuote.length();
    } else {
        // no special treatment required
        strbuf.append(comp.charAt(i++));
    }
      }

      // end with closing quote
      strbuf.append(endQuote);

  } else {

      // When component is not quoted, add escape for:
      // 1. leading quote 
      // 2. an escape preceding any meta char
      // 3. an escape at the end of a component
      // 4. separator

      // go through characters in component and escape where necessary
      boolean start = true;
      for (int i = 0; i < len; ) {
    // leading quote must be escaped
    if (start && isA(comp, i, syntaxBeginQuote1)) {
        strbuf.append(syntaxEscape).append(syntaxBeginQuote1);
        i += syntaxBeginQuote1.length();
    } else if (start && isA(comp, i, syntaxBeginQuote2)) {
        strbuf.append(syntaxEscape).append(syntaxBeginQuote2);
        i += syntaxBeginQuote2.length();
    } else

    // Escape an escape preceding meta characters, or at end.
    // Other escapes pass through.
    if (isA(comp, i, syntaxEscape)) {
        if (i + syntaxEscape.length() >= len) {
      // escape an ending escape
      strbuf.append(syntaxEscape);
        } else if (isMeta(comp, i + syntaxEscape.length())) {
      // escape meta strings
      strbuf.append(syntaxEscape);
        }
        strbuf.append(syntaxEscape);
        i += syntaxEscape.length();
    } else

    // escape unescaped separator
    if (escapeSeparator && comp.startsWith(syntaxSeparator, i)) {
        // escape separator
        strbuf.append(syntaxEscape).append(syntaxSeparator);
        i += syntaxSeparator.length();
    } else if (escapeSeparator2 &&
         comp.startsWith(syntaxSeparator2, i)) {
        // escape separator2
        strbuf.append(syntaxEscape).append(syntaxSeparator2);
        i += syntaxSeparator2.length();
    } else {
        // no special treatment required
        strbuf.append(comp.charAt(i++));
    }
    start = false;
      }
  }
  return (strbuf.toString());
    }

    public String toString() {
  StringBuffer answer = new StringBuffer();
  String comp;
  boolean compsAllEmpty = true;
  int size = components.size();

  for (int i = 0; i < size; i++) {
      if (syntaxDirection == RIGHT_TO_LEFT) {
    comp =
        stringifyComp((String) components.elementAt(size - 1 - i));
      } else {
    comp = stringifyComp((String) components.elementAt(i));
      }
      if ((i != 0) && (syntaxSeparator != null))
    answer.append(syntaxSeparator);
      if (comp.length() >= 1)
    compsAllEmpty = false;
      answer = answer.append(comp);
  }
  if (compsAllEmpty && (size >= 1) && (syntaxSeparator != null))
      answer = answer.append(syntaxSeparator);
  return (answer.toString());
    }

    public boolean equals(Object obj) {
  if ((obj != null) && (obj instanceof NameImpl)) {
      NameImpl target = (NameImpl)obj;
      if (target.size() ==  this.size()) {
    Enumeration mycomps = getAll();
    Enumeration comps = target.getAll();
    while (mycomps.hasMoreElements()) {
        // %% comps could shrink in the middle.
        String my = (String)mycomps.nextElement();
        String his = (String)comps.nextElement();
        if (syntaxTrimBlanks) {
      my = my.trim();
      his = his.trim();
        }
        if (syntaxCaseInsensitive) {
      if (!(my.equalsIgnoreCase(his)))
          return false;
        } else {
      if (!(my.equals(his)))
          return false;
        }
    }
    return true;
      }
  }
  return false;
    }

    /**
      * Compares obj to this NameImpl to determine ordering.
      * Takes into account syntactic properties such as
      * elimination of blanks, case-ignore, etc, if relevant.
      *
      * Note: using syntax of this NameImpl and ignoring
      * that of comparison target.
      */
    public int compareTo(NameImpl obj) {
  if (this == obj) {
      return 0;
  }

  int len1 = size();
  int len2 = obj.size();
  int n = Math.min(len1, len2);

  int index1 = 0, index2 = 0;

  while (n-- != 0) {
      String comp1 = get(index1++);
      String comp2 = obj.get(index2++);

      // normalize according to syntax
      if (syntaxTrimBlanks) {
    comp1 = comp1.trim();
    comp2 = comp2.trim();
      }
      if (syntaxCaseInsensitive) {
    comp1 = comp1.toLowerCase();
    comp2 = comp2.toLowerCase();
      }
      int local = comp1.compareTo(comp2);
      if (local != 0) {
    return local;
      }
  }

  return len1 - len2;
    }

    public int size() {
  return (components.size());
    }

    public Enumeration getAll() {
  return components.elements();
    }

    public String get(int posn) {
  return ((String) components.elementAt(posn));
    }

    public Enumeration getPrefix(int posn) {
  if (posn < 0 || posn > size()) {
      throw new ArrayIndexOutOfBoundsException(posn);
  }
  return new NameImplEnumerator(components, 0, posn);
    }

    public Enumeration getSuffix(int posn) {
  int cnt = size();
  if (posn < 0 || posn > cnt) {
      throw new ArrayIndexOutOfBoundsException(posn);
  }
  return new NameImplEnumerator(components, posn, cnt);
    }

    public boolean isEmpty() {
  return (components.isEmpty());
    }

    public boolean startsWith(int posn, Enumeration prefix) {
  if (posn < 0 || posn > size()) {
      return false;
  }
  try {
      Enumeration mycomps = getPrefix(posn);
      while (mycomps.hasMoreElements()) {
    String my = (String)mycomps.nextElement();
    String his = (String)prefix.nextElement();
    if (syntaxTrimBlanks) {
        my = my.trim();
        his = his.trim();
    }
    if (syntaxCaseInsensitive) {
        if (!(my.equalsIgnoreCase(his)))
      return false;
    } else {
        if (!(my.equals(his)))
      return false;
    }
      }
  } catch (NoSuchElementException e) {
      return false;
  }
  return true;
    }

    public boolean endsWith(int posn, Enumeration suffix) {
  // posn is number of elements in suffix
  // startIndex is the starting position in this name
  // at which to start the comparison. It is calculated by
  // subtracting 'posn' from size()
  int startIndex = size() - posn;
  if (startIndex < 0 || startIndex > size()) {
      return false;
  }
  try {
      Enumeration mycomps = getSuffix(startIndex);
      while (mycomps.hasMoreElements()) {
    String my = (String)mycomps.nextElement();
    String his = (String)suffix.nextElement();
    if (syntaxTrimBlanks) {
        my = my.trim();
        his = his.trim();
    }
    if (syntaxCaseInsensitive) {
        if (!(my.equalsIgnoreCase(his)))
      return false;
    } else {
        if (!(my.equals(his)))
      return false;
    }
      }
  } catch (NoSuchElementException e) {
      return false;
  }
  return true;
    }

    public boolean addAll(Enumeration comps) throws InvalidNameException {
  boolean added = false;
  while (comps.hasMoreElements()) {
      try {
    Object comp = comps.nextElement();
    if (size() > 0 && syntaxDirection == FLAT) {
        throw new InvalidNameException(
      "A flat name can only have a single component");
    }
    components.addElement(comp);
    added = true;
      } catch (NoSuchElementException e) {
    break;  // "comps" has shrunk.
      }
  }
  return added;
    }

    public boolean addAll(int posn, Enumeration comps) 
    throws InvalidNameException {
  boolean added = false;
  for (int i = posn; comps.hasMoreElements(); i++) {
      try {
    Object comp = comps.nextElement();
    if (size() > 0 && syntaxDirection == FLAT) {
        throw new InvalidNameException(
      "A flat name can only have a single component");
    }
    components.insertElementAt(comp, i);
    added = true;
      } catch (NoSuchElementException e) {
    break;  // "comps" has shrunk.
      }
  }
  return added;
    }

    public void add(String comp) throws InvalidNameException {
  if (size() > 0 && syntaxDirection == FLAT) {
      throw new InvalidNameException(
    "A flat name can only have a single component");
  }
  components.addElement(comp);
    }

    public void add(int posn, String comp) throws InvalidNameException {
  if (size() > 0 && syntaxDirection == FLAT) {
      throw new InvalidNameException(
    "A flat name can only zero or one component");
  }
  components.insertElementAt(comp, posn);
    }

    public Object remove(int posn) {
  Object r = components.elementAt(posn);
  components.removeElementAt(posn);
  return r;
    }

    public int hashCode() {
  int hash = 0;
  for (Enumeration e = getAll(); e.hasMoreElements();) {
      String comp = (String)e.nextElement();
      if (syntaxTrimBlanks) {
    comp = comp.trim();
      }
      if (syntaxCaseInsensitive) {
    comp = comp.toLowerCase();
      }
  
      hash += comp.hashCode();
  }
  return hash;
    }
}

final
class NameImplEnumerator implements Enumeration {
    Vector vector;
    int count;
    int limit;

    NameImplEnumerator(Vector v, int start, int lim) {
  vector = v;
  count = start;
  limit = lim;
    }

    public boolean hasMoreElements() {
  return count < limit;
    }

    public Object nextElement() {
  if (count < limit) {
      return vector.elementAt(count++);
  }
  throw new NoSuchElementException("NameImplEnumerator");
    }
}

java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.