001: /*
002: * Copyright 2004-2006 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.compass.core.engine.naming;
018:
019: import java.util.Arrays;
020:
021: import org.compass.core.util.StringUtils;
022:
023: /**
024: * A dynamic path implementations. Holds the path elements in an array,
025: * and constrcut it each time {@link #getPath()} is called.
026: * <p/>
027: * Benefits of using this implementation is its low memory footprint,
028: * while extra processing is made for runtime path construction
029: * (mainly during marshalling/unmarshalling operations)
030: * <p/>
031: * {@link #hintStatic()} uses the same implementation, and retains its dynamic nature.
032: *
033: * @author kimchy
034: * @author lexi
035: * @see DynamicPropertyNamingStrategy
036: */
037: public class DynamicPropertyPath implements PropertyPath {
038:
039: private final String[] steps;
040:
041: private static final char delimiter = '/';
042:
043: private int hash;
044:
045: public DynamicPropertyPath(String step) {
046: this .steps = new String[] { step.intern() };
047: }
048:
049: public DynamicPropertyPath(String[] steps) {
050: this .steps = steps;
051: }
052:
053: public DynamicPropertyPath(PropertyPath root, String name) {
054: if (root instanceof DynamicPropertyPath) {
055: String[] rootSteps = ((DynamicPropertyPath) root).steps;
056: steps = new String[rootSteps.length + 1];
057: System.arraycopy(rootSteps, 0, steps, 0, rootSteps.length);
058: steps[rootSteps.length] = name.intern();
059: } else {
060: steps = new String[2];
061: steps[0] = root.getPath();
062: steps[1] = name.intern();
063: }
064: }
065:
066: public String getPath() {
067: return StringUtils.arrayToDelimitedString(steps, delimiter);
068: }
069:
070: public PropertyPath hintStatic() {
071: return this ;
072: }
073:
074: public boolean equals(Object obj) {
075:
076: if (this == obj) {
077: return true;
078: }
079: if ((null == obj) || (!(obj instanceof PropertyPath))) {
080: return false;
081: }
082:
083: if (obj instanceof DynamicPropertyPath) {
084: final DynamicPropertyPath path = (DynamicPropertyPath) obj;
085: return Arrays.equals(steps, path.steps);
086: } else {
087: final PropertyPath path = (PropertyPath) obj;
088: return getPath().equals(path.getPath());
089: }
090: }
091:
092: public int hashCode() {
093: int h = hash;
094: if (h == 0) {
095: for (int index = 0; index < steps.length; index++) {
096: if (index > 0)
097: h = h * 31 + delimiter;
098: h = hashCode(h, steps[index]);
099: }
100: hash = h;
101: }
102: return h;
103: }
104:
105: private int hashCode(final int hash, String string) {
106: int h = hash;
107: for (int i = 0; i < string.length(); i++) {
108: h = h * 31 + string.charAt(i);
109: }
110: return h;
111:
112: }
113: }
|