001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.openejb.core.ivm.naming;
017:
018: public class ParsedName implements java.io.Serializable {
019: final static int IS_EQUAL = 0;
020: final static int IS_LESS = -1;
021: final static int IS_GREATER = 1;
022:
023: String[] components;
024: int pos = 0;
025: int hashcode;
026:
027: public ParsedName(String path) {
028: path = normalize(path);
029:
030: if (path == null || path.equals("/")) {
031:
032: components = new String[1];
033: components[0] = "";
034: hashcode = 0;
035: } else if (path.length() > 0) {
036: java.util.StringTokenizer st = new java.util.StringTokenizer(
037: path, "/");
038: components = new String[st.countTokens()];
039: for (int i = 0; st.hasMoreTokens() && i < components.length; i++)
040: components[i] = st.nextToken();
041: hashcode = components[0].hashCode();
042: } else {
043:
044: components = new String[1];
045: components[0] = "";
046: hashcode = 0;
047: }
048: }
049:
050: public String getComponent() {
051: return components[pos];
052: }
053:
054: public boolean next() {
055: if (components.length > pos + 1) {
056: hashcode = components[++pos].hashCode();
057: return true;
058: } else {
059: return false;// maintain position
060: }
061: }
062:
063: public void reset() {
064: pos = 0;
065: hashcode = components[0].hashCode();
066: }
067:
068: public int compareTo(int otherHash) {
069: if (hashcode == otherHash)
070: return 0;
071: else if (hashcode > otherHash)
072: return 1;
073: else
074: return -1;
075: }
076:
077: public int getComponentHashCode() {
078: return hashcode;
079: }
080:
081: public int compareTo(String other) {
082: int otherHash = other.hashCode();
083: return compareTo(otherHash);
084: }
085:
086: public static void main(String[] args) {
087:
088: ParsedName name = new ParsedName("comp/env/jdbc/mydatabase");
089: while (name.next())
090: System.out.println(name.getComponent());
091: }
092:
093: public String toString() {
094: if (components.length == 0) {
095: return "";
096: }
097: StringBuffer buffer = new StringBuffer(components[0]);
098: for (int i = 1; i < components.length; ++i) {
099: buffer.append('/');
100: buffer.append(components[i]);
101: }
102: return buffer.toString();
103: }
104:
105: /* A normal Unix pathname contains no duplicate slashes and does not end
106: with a slash. It may be the empty string. */
107:
108: /* Normalize the given pathname, whose length is len, starting at the given
109: offset; everything before this offset is already normal. */
110: private String normalize(String pathname, int len, int off) {
111: if (len == 0)
112: return pathname;
113: int n = len;
114: while ((n > 0) && (pathname.charAt(n - 1) == '/'))
115: n--;
116: if (n == 0)
117: return "/";
118: StringBuffer sb = new StringBuffer(pathname.length());
119: if (off > 0)
120: sb.append(pathname.substring(0, off));
121: char prevChar = 0;
122: for (int i = off; i < n; i++) {
123: char c = pathname.charAt(i);
124: if ((prevChar == '/') && (c == '/'))
125: continue;
126: sb.append(c);
127: prevChar = c;
128: }
129: return sb.toString();
130: }
131:
132: /* Check that the given pathname is normal. If not, invoke the real
133: normalizer on the part of the pathname that requires normalization.
134: This way we iterate through the whole pathname string only once. */
135: private String normalize(String pathname) {
136: int n = pathname.length();
137: char prevChar = 0;
138: for (int i = 0; i < n; i++) {
139: char c = pathname.charAt(i);
140: if ((prevChar == '/') && (c == '/'))
141: return normalize(pathname, n, i - 1);
142: prevChar = c;
143: }
144: if (prevChar == '/')
145: return normalize(pathname, n, n - 1);
146: return pathname;
147: }
148:
149: }
|