blob: 131774cb1ddf70e71e28a258d465d3268e9ea80e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ptp.internal.rdt.core.search;
import java.io.Serializable;
import org.eclipse.cdt.core.CConventions;
import org.eclipse.cdt.core.browser.IQualifiedTypeName;
import org.eclipse.core.runtime.IStatus;
public class RemoteQualifiedTypeName implements IQualifiedTypeName, Serializable {
private static final long serialVersionUID = 1L;
private static final String[] NO_SEGMENTS = new String[0];
private static final String EMPTY_STRING = ""; //$NON-NLS-1$
private static final int INITIAL_SEGMENT_LENGTH = 12;
private static final int HASH_INIT = 17;
private static final int HASH_MULTIPLIER = 37;
private String[] fSegments = NO_SEGMENTS;
private int fHashCode = 0;
public static final RemoteQualifiedTypeName EMPTY = new RemoteQualifiedTypeName();
public RemoteQualifiedTypeName(IQualifiedTypeName typeName) {
fSegments = typeName.segments();
}
public RemoteQualifiedTypeName(String qualifiedName) {
fSegments = createSegments(qualifiedName);
}
public RemoteQualifiedTypeName(String[] names) {
fSegments = createSegments(names);
}
public RemoteQualifiedTypeName(String name, String[] enclosingNames) {
if (enclosingNames == null)
fSegments = createSegments(name);
else
fSegments = createSegments(name, enclosingNames);
}
private RemoteQualifiedTypeName() {
}
private String[] createSegments(String qualifiedName) {
String[] segments;
int qualifierIndex = qualifiedName.indexOf(QUALIFIER, 0);
if (qualifierIndex == -1) {
segments = new String[] { qualifiedName };
} else {
int maxSegments = 1;
int lastIndex = 0;
while (qualifierIndex >= 0) {
lastIndex = qualifierIndex + QUALIFIER.length();
++maxSegments;
qualifierIndex = qualifiedName.indexOf(QUALIFIER, lastIndex);
}
segments = new String[maxSegments];
int segmentCount = 0;
lastIndex = 0;
qualifierIndex = qualifiedName.indexOf(QUALIFIER, 0);
while (qualifierIndex >= 0) {
// note: we allocate a new string rather than use the returned substring,
// otherwise we're holding a reference to the entire original string
segments[segmentCount] = new String(qualifiedName.substring(lastIndex, qualifierIndex));
++segmentCount;
lastIndex = qualifierIndex + QUALIFIER.length();
qualifierIndex = qualifiedName.indexOf(QUALIFIER, lastIndex);
}
// note: we allocate a new string rather than use the returned substring,
// otherwise we're holding a reference to the entire original string
segments[segmentCount] = new String(qualifiedName.substring(lastIndex));
}
return segments;
}
private String[] createSegments(String[] names) {
String[] segments = new String[names.length];
System.arraycopy(names, 0, segments, 0, names.length);
return segments;
}
private String[] createSegments(String name, String[] enclosingNames) {
String[] segments = new String[enclosingNames.length + 1];
System.arraycopy(enclosingNames, 0, segments, 0, enclosingNames.length);
segments[segments.length - 1] = name;
return segments;
}
public String getName() {
if (fSegments.length > 0) {
return fSegments[fSegments.length - 1];
}
return EMPTY_STRING;
}
public String[] getEnclosingNames() {
if (fSegments.length > 1) {
String[] enclosingNames = new String[fSegments.length - 1];
System.arraycopy(fSegments, 0, enclosingNames, 0, fSegments.length - 1);
return enclosingNames;
}
return NO_SEGMENTS;
}
public String getFullyQualifiedName() {
if (fSegments.length > 0) {
StringBuffer buf = new StringBuffer(fSegments.length * INITIAL_SEGMENT_LENGTH);
for (int i = 0; i < fSegments.length; ++i) {
if (i > 0) {
buf.append(QUALIFIER);
}
buf.append(fSegments[i]);
}
return buf.toString();
}
return EMPTY_STRING;
}
public IQualifiedTypeName getEnclosingTypeName() {
String[] enclosingNames = getEnclosingNames();
if (enclosingNames.length > 0) {
RemoteQualifiedTypeName enclosingTypeName = new RemoteQualifiedTypeName();
enclosingTypeName.fSegments = enclosingNames;
return enclosingTypeName;
}
return null;
}
public boolean isQualified() {
return (fSegments.length > 1);
}
public boolean isEmpty() {
return (fSegments.length == 0);
}
public boolean isGlobal() {
return (fSegments.length <= 1 || fSegments[0].length() == 0);
}
public int segmentCount() {
return fSegments.length;
}
public String[] segments() {
String[] segmentCopy = new String[fSegments.length];
System.arraycopy(fSegments, 0, segmentCopy, 0, fSegments.length);
return segmentCopy;
}
public String segment(int index) {
if (index >= fSegments.length) {
return null;
}
return fSegments[index];
}
public String lastSegment() {
if (fSegments.length > 0) {
return fSegments[fSegments.length - 1];
}
return null;
}
public int matchingFirstSegments(IQualifiedTypeName typeName) {
int max = Math.min(fSegments.length, typeName.segmentCount());
int count = 0;
for (int i = 0; i < max; ++i) {
if (!fSegments[i].equals(typeName.segment(i))) {
return count;
}
++count;
}
return count;
}
public boolean isPrefixOf(IQualifiedTypeName typeName) {
if (fSegments.length == 0)
return true;
if (fSegments.length > typeName.segmentCount()) {
return false;
}
for (int i = 0; i < fSegments.length; ++i) {
if (!fSegments[i].equals(typeName.segment(i))) {
return false;
}
}
return true;
}
public IQualifiedTypeName append(String[] names) {
int length = fSegments.length;
int typeNameLength = names.length;
String[] newSegments = new String[length + typeNameLength];
System.arraycopy(fSegments, 0, newSegments, 0, length);
System.arraycopy(names, 0, newSegments, length, typeNameLength);
RemoteQualifiedTypeName newTypeName = new RemoteQualifiedTypeName();
newTypeName.fSegments = newSegments;
return newTypeName;
}
public IQualifiedTypeName append(IQualifiedTypeName typeName) {
int length = fSegments.length;
int typeNameLength = typeName.segmentCount();
String[] newSegments = new String[length + typeNameLength];
System.arraycopy(fSegments, 0, newSegments, 0, length);
for (int i = 0; i < typeNameLength; ++i) {
newSegments[i + length] = typeName.segment(i);
}
RemoteQualifiedTypeName newTypeName = new RemoteQualifiedTypeName();
newTypeName.fSegments = newSegments;
return newTypeName;
}
public IQualifiedTypeName append(String qualifiedName) {
return append(createSegments(qualifiedName));
}
public IQualifiedTypeName removeFirstSegments(int count) {
if (count == 0) {
return this;
} else if (count >= fSegments.length || count < 0) {
return EMPTY;
} else {
int newSize = fSegments.length - count;
String[] newSegments = new String[newSize];
System.arraycopy(fSegments, count, newSegments, 0, newSize);
RemoteQualifiedTypeName newTypeName = new RemoteQualifiedTypeName();
newTypeName.fSegments = newSegments;
return newTypeName;
}
}
public IQualifiedTypeName removeLastSegments(int count) {
if (count == 0) {
return this;
} else if (count >= fSegments.length || count < 0) {
return EMPTY;
} else {
int newSize = fSegments.length - count;
String[] newSegments = new String[newSize];
System.arraycopy(fSegments, 0, newSegments, 0, newSize);
RemoteQualifiedTypeName newTypeName = new RemoteQualifiedTypeName();
newTypeName.fSegments = newSegments;
return newTypeName;
}
}
public boolean isLowLevel() {
for (int i = 0; i < fSegments.length; ++i) {
if (fSegments[i].startsWith("_")) { //$NON-NLS-1$
return true;
}
}
return false;
}
public boolean isValid() {
for (int i = 0; i < fSegments.length; ++i) {
String segment = fSegments[i];
// type name must follow C conventions
IStatus val = CConventions.validateIdentifier(segment);
if (val.getSeverity() == IStatus.ERROR)
return false;
}
return true;
}
public boolean isValidSegment(String segment) {
if (segment.indexOf(QUALIFIER) != -1)
return false;
// type name must follow C conventions
IStatus val = CConventions.validateIdentifier(segment);
return (val.getSeverity() != IStatus.ERROR);
}
@Override
public int hashCode() {
if (fHashCode == 0) {
fHashCode = HASH_INIT;
for (int i = 0; i < fSegments.length; ++i) {
fHashCode = fHashCode * HASH_MULTIPLIER + fSegments[i].hashCode();
}
}
return fHashCode;
}
@Override
public String toString() {
return getFullyQualifiedName();
}
public int compareTo(IQualifiedTypeName typeName) {
if (typeName == this)
return 0;
if (typeName == null)
return 1;
int length = fSegments.length;
int typeNameLength = typeName.segmentCount();
int len = Math.min(length, typeNameLength);
int result = 0;
for (int i = 0; result == 0 && i < len; ++i) {
result = fSegments[i].compareTo(typeName.segment(i));
}
if (result == 0 && length != typeNameLength) {
result = (length < typeNameLength) ? -1 : 1;
}
return result;
}
public int compareToIgnoreCase(IQualifiedTypeName typeName) {
if (typeName == this)
return 0;
if (typeName == null)
return 1;
int length = fSegments.length;
int typeNameLength = typeName.segmentCount();
int len = Math.min(length, typeNameLength);
int result = 0;
for (int i = 0; result == 0 && i < len; ++i) {
result = fSegments[i].compareToIgnoreCase(typeName.segment(i));
}
if (result == 0 && length != typeNameLength) {
result = (length < typeNameLength) ? -1 : 1;
}
return result;
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof IQualifiedTypeName)) {
return false;
}
return equals((IQualifiedTypeName)obj);
}
public boolean equals(IQualifiedTypeName typeName) {
if (typeName == this)
return true;
if (typeName == null)
return false;
int length = fSegments.length;
int typeNameLength = typeName.segmentCount();
if (length != typeNameLength)
return false;
for (int i = 0; i < length; ++i) {
if (!fSegments[i].equals(typeName.segment(i)))
return false;
}
return true;
}
public boolean equalsIgnoreCase(IQualifiedTypeName typeName) {
if (typeName == this)
return true;
if (typeName == null)
return false;
int length = fSegments.length;
int typeNameLength = typeName.segmentCount();
if (length != typeNameLength)
return false;
for (int i = 0; i < length; ++i) {
if (!fSegments[i].equalsIgnoreCase(typeName.segment(i)))
return false;
}
return true;
}
}