📄 configurationkey.java
字号:
if(it1.isAttribute())
{
result.appendAttribute(it1.currentKey());
} /* if */
else
{
result.append(it1.currentKey());
if(it1.hasIndex)
{
result.appendIndex(it1.getIndex());
} /* if */
} /* else */
} /* while */
return result;
}
/**
* Returns the "difference key" to a given key. This value
* is the part of the passed in key that differs from this key. There is
* the following relation:
* <code>other = key.commonKey(other) + key.differenceKey(other)</code>
* for an arbitrary configuration key <code>key</code>.
* @param other the key for which the difference is to be calculated
* @return the difference key
*/
public ConfigurationKey differenceKey(ConfigurationKey other)
{
ConfigurationKey common = commonKey(other);
ConfigurationKey result = new ConfigurationKey();
if(common.length() < other.length())
{
String k = other.toString().substring(common.length());
// skip trailing delimiters
int i = 0;
while(i < k.length() && k.charAt(i) == PROPERTY_DELIMITER)
{
i++;
} /* while */
if(i < k.length())
{
result.append(k.substring(i));
} /* if */
} /* if */
return result;
}
/**
* Helper method for comparing two key parts.
* @param it1 the iterator with the first part
* @param it2 the iterator with the second part
* @return a flag if both parts are equal
*/
private static boolean partsEqual(KeyIterator it1, KeyIterator it2)
{
return it1.nextKey().equals(it2.nextKey())
&& it1.getIndex() == it2.getIndex()
&& it1.isAttribute() == it2.isAttribute();
}
/**
* A specialized iterator class for tokenizing a configuration key.
* This class implements the normal iterator interface. In addition it
* provides some specific methods for configuration keys.
*
* @author <a href="mailto:oliver.heger@t-online.de">Oliver Heger</a>
*/
public class KeyIterator implements Iterator, Cloneable
{
/** Stores the current key name.*/
private String current;
/** Stores the start index of the actual token.*/
private int startIndex;
/** Stores the end index of the actual token.*/
private int endIndex;
/** Stores the index of the actual property if there is one.*/
private int indexValue;
/** Stores a flag if the actual property has an index.*/
private boolean hasIndex;
/** Stores a flag if the actual property is an attribute.*/
private boolean attribute;
/**
* Helper method for determining the next indices.
*/
private void findNextIndices()
{
startIndex = endIndex;
// skip empty names
while (startIndex < keyBuffer.length()
&& keyBuffer.charAt(startIndex) == PROPERTY_DELIMITER)
{
startIndex++;
}
// Key ends with a delimiter?
if (startIndex >= keyBuffer.length())
{
endIndex = keyBuffer.length();
startIndex = endIndex - 1;
}
else
{
String s = keyBuffer.toString(); // for compatibility
endIndex = s.indexOf(PROPERTY_DELIMITER, startIndex);
if (endIndex < 0)
{
endIndex = s.indexOf(ATTRIBUTE_START, startIndex);
if (endIndex < 0 || endIndex == startIndex)
{
endIndex = keyBuffer.length();
}
}
}
}
/**
* Returns the next key part of this configuration key. This is a short
* form of <code>nextKey(false)</code>.
* @return the next key part
*/
public String nextKey()
{
return nextKey(false);
}
/**
* Returns the next key part of this configuration key. The boolean
* parameter indicates wheter a decorated key should be returned. This
* affects only attribute keys: if the parameter is <b>false</b>, the
* attribute markers are stripped from the key; if it is <b>true</b>,
* they remain.
* @param decorated a flag if the decorated key is to be returned
* @return the next key part
*/
public String nextKey(boolean decorated)
{
if(!hasNext())
{
throw new NoSuchElementException("No more key parts!");
} /* if */
hasIndex = false;
indexValue = -1;
findNextIndices();
String key = keyBuffer.substring(startIndex, endIndex).toString();
attribute = checkAttribute(key);
if(!attribute)
{
hasIndex = checkIndex(key);
if(!hasIndex)
{
current = key;
} /* if */
} /* if */
return currentKey(decorated);
}
/**
* Helper method for checking if the passed key is an attribute.
* If this is the case, the internal fields will be set.
* @param key the key to be checked
* @return a flag if the key is an attribute
*/
private boolean checkAttribute(String key)
{
if(isAttributeKey(key))
{
current = removeAttributeMarkers(key);
return true;
} /* if */
else
{
return false;
} /* else */
}
/**
* Helper method for checking if the passed key contains an index.
* If this is the case, internal fields will be set.
* @param key the key to be checked
* @return a flag if an index is defined
*/
private boolean checkIndex(String key)
{
boolean result = false;
int idx = key.indexOf(INDEX_START);
if(idx > 0)
{
int endidx = key.indexOf(INDEX_END, idx);
if(endidx > idx + 1)
{
indexValue = Integer.parseInt(key.substring(idx+1, endidx));
current = key.substring(0, idx);
result = true;
} /* if */
} /* if */
return result;
}
/**
* Checks if there is a next element.
* @return a flag if there is a next element
*/
public boolean hasNext()
{
return endIndex < keyBuffer.length();
}
/**
* Returns the next object in the iteration.
* @return the next object
*/
public Object next()
{
return nextKey();
}
/**
* Removes the current object in the iteration. This method is not
* supported by this iterator type, so an exception is thrown.
*/
public void remove()
{
throw new UnsupportedOperationException("Remove not supported!");
}
/**
* Returns the current key of the iteration (without skipping to the
* next element). This is the same key the previous <code>next()</code>
* call had returned. (Short form of <code>currentKey(false)</code>.
* @return the current key
*/
public String currentKey()
{
return currentKey(false);
}
/**
* Returns the current key of the iteration (without skipping to the
* next element). The boolean parameter indicates wheter a decorated
* key should be returned. This affects only attribute keys: if the
* parameter is <b>false</b>, the attribute markers are stripped from
* the key; if it is <b>true</b>, they remain.
* @param decorated a flag if the decorated key is to be returned
* @return the current key
*/
public String currentKey(boolean decorated)
{
return (decorated && isAttribute()) ?
constructAttributeKey(current) : current;
}
/**
* Returns a flag if the current key is an attribute. This method can
* be called after <code>next()</code>.
* @return a flag if the current key is an attribute
*/
public boolean isAttribute()
{
return attribute;
}
/**
* Returns the index value of the current key. If the current key does
* not have an index, return value is -1. This method can be called
* after <code>next()</code>.
* @return the index value of the current key
*/
public int getIndex()
{
return indexValue;
}
/**
* Returns a flag if the current key has an associated index.
* This method can be called after <code>next()</code>.
* @return a flag if the current key has an index
*/
public boolean hasIndex()
{
return hasIndex;
}
/**
* Creates a clone of this object.
* @return a clone of this object
*/
protected Object clone()
{
try
{
return super.clone();
} /* try */
catch(CloneNotSupportedException cex)
{
// should not happen
return null;
} /* catch */
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -