Com um plug-in MapIndexPlugin, ou índice, é possível gravar estratégias de indexação customizadas que vão além de índices integrados fornecidos pelo eXtreme Scale.
As implementações MapIndexPlugin devem usar a interface MapIndexPlugin e seguir as convenções comuns do plug-in do eXtreme Scale.
As seções a seguir incluem alguns dos métodos importantes da interface de índice.
Use o método setProperties para inicializar programaticamente do plug-in de índice. O parâmetro Objeto de propriedades transmitido para o método deve conter as informações necessárias sobre configuração para inicializar o plug-in de índice adequadamente. A implementação do método setProperties, junto com a do método getProperties, são necessárias em um ambiente distribuído pois a configuração do plug-in de índice se move entre os processos do cliente e do servidor. A seguir está um exemplo de implementação deste método.
setProperties(Properties properties)
// setProperties method sample code
public void setProperties(Properties properties) {
ivIndexProperties = properties;
String ivRangeIndexString = properties.getProperty("rangeIndex");
if (ivRangeIndexString != null && ivRangeIndexString.equals("true")) {
setRangeIndex(true);
}
setName(properties.getProperty("indexName"));
setAttributeName(properties.getProperty("attributeName"));
String ivFieldAccessAttributeString = properties.getProperty("fieldAccessAttribute");
if (ivFieldAccessAttributeString != null && ivFieldAccessAttributeString.equals("true")) {
setFieldAccessAttribute(true);
}
String ivPOJOKeyIndexString = properties.getProperty("POJOKeyIndex");
if (ivPOJOKeyIndexString != null && ivPOJOKeyIndexString.equals("true")) {
setPOJOKeyIndex(true);
}
}
O método getProperties extrai a configuração do plug-in de índice de uma instância MapIndexPlugin. É possível usar as propriedades extraídas para inicializar outra instância do MapIndexPlugin para ter os mesmos estados internos. Os implementações dos métodos getProperties e setProperties são necessárias em um ambiente distribuído. A seguir há um exemplo de implementação do método getProperties.
getProperties()
// getProperties method sample code
public Properties getProperties() {
Properties p = new Properties();
p.put("indexName", indexName);
p.put("attributeName", attributeName);
p.put("rangeIndex", ivRangeIndex ? "true" : "false");
p.put("fieldAccessAttribute", ivFieldAccessAttribute ? "true" : "false");
p.put("POJOKeyIndex", ivPOJOKeyIndex ? "true" : "false");
return p;
}
O método setEntityMetadata é chamado pelo tempo de execução do WebSphere eXtreme Scale durante a inicialização para configurar EntityMetadata do BackingMap associado na instância MapIndexPlugin. O EntityMetadata é necessário para suportar a indexação de objetos de tupla. Uma tupla é um conjunto de dados que representa um objeto da entidade ou sua chave. Se o BackingMap for para uma entidade, então, é necessário implementar este método.
O código de amostra a seguir implementa o método setEntityMetadata.
setEntityMetadata(EntityMetadata entityMetadata)
// setEntityMetadata method sample code
public void setEntityMetadata(EntityMetadata entityMetadata) {
ivEntityMetadata = entityMetadata;
if (ivEntityMetadata != null) {
// este é um mapa de tupla
TupleMetadata valueMetadata = ivEntityMetadata.getValueMetadata();
int numAttributes = valueMetadata.getNumAttributes();
for (int i = 0; i < numAttributes; i++) {
String tupleAttributeName = valueMetadata.getAttribute(i).getName();
if (attributeName.equals(tupleAttributeName)) {
ivTupleValueIndex = i;
break;
}
}
if (ivTupleValueIndex == -1) {
// did not find the attribute in value tuple, try to find it on key tuple.
// if found on key tuple, implies key indexing on one of tuple key attributes.
TupleMetadata keyMetadata = ivEntityMetadata.getKeyMetadata();
numAttributes = keyMetadata.getNumAttributes();
for (int i = 0; i < numAttributes; i++) {
String tupleAttributeName = keyMetadata.getAttribute(i).getName();
if (attributeName.equals(tupleAttributeName)) {
ivTupleValueIndex = i;
ivKeyTupleAttributeIndex = true;
break;
}
}
}
if (ivTupleValueIndex == -1) {
// if entityMetadata is not null and we could not find the
// attributeName in entityMetadata, this is an
// error
throw new ObjectGridRuntimeException("Invalid attributeName. Entity: " + ivEntityMetadata.getName());
}
}
}
O método setAttributeName configura o nome do atributo a ser indexado. A classe de objeto de cache deve fornecer o método get para o atributo indexado. Por exemplo, se o objeto possuir um atributo employeeName ou EmployeeName, o índice chama o método getEmployeeName no objeto para extrair o valor de atributo. O nome do atributo deve ser o mesmo nome no método get e o atributo deve implementar a interface Comparable. Se o atributo for do tipo booleano, também é possível utilizar o método padrão isAttributeName.
O método getAttributeName retorna o nome do atributo indexado.
O método getAttribute retorna o valor de atributo indexado do objeto especificado. Por exemplo, se um objeto Employee possui um atributo denominado employeeName que é indexado, o método getAttribute pode ser utilizado para extrair o valor de atributo employeeName de um objeto Employee especificado. Este método é necessário em um ambiente WebSphere eXtreme Scale distribuído.
getAttribute(Object value)
// getAttribute method sample code
public Object getAttribute(Object value) throws ObjectGridRuntimeException {
if (ivPOJOKeyIndex) {
// In the POJO key indexing case, no need to get attribute from value object.
// The key itself is the attribute value used to build the index.
return null;
}
try {
Object attribute = null;
if (value != null) {
// handle Tuple value if ivTupleValueIndex != -1
if (ivTupleValueIndex == -1) {
// regular value
if (ivFieldAccessAttribute) {
attribute = this.getAttributeField(value).get(value);
} else {
attribute = getAttributeMethod(value).invoke(value, emptyArray);
}
} else {
// Tuple value
attribute = extractValueFromTuple(value);
}
}
return attribute;
} catch (InvocationTargetException e) {
throw new ObjectGridRuntimeException(
"Caught unexpected Throwable during index update processing, index name = " + indexName + ": " + t,
t);
} catch (Throwable t) {
throw new ObjectGridRuntimeException(
"Caught unexpected Throwable during index update processing, index name = " + indexName + ": " + t,
t);
}
}