/*
* Copyright 2012 Amazon Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://aws.amazon.com/apache2.0
*
* This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
* OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and
* limitations under the License.
*/
package com.amazonaws.eclipse.explorer.dynamodb;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ColumnPixelData;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import com.amazonaws.eclipse.core.AwsToolkitCore;
import com.amazonaws.services.dynamodbv2.model.AttributeDefinition;
import com.amazonaws.services.dynamodbv2.model.DescribeTableRequest;
import com.amazonaws.services.dynamodbv2.model.KeySchemaElement;
import com.amazonaws.services.dynamodbv2.model.KeyType;
import com.amazonaws.services.dynamodbv2.model.LocalSecondaryIndexDescription;
import com.amazonaws.services.dynamodbv2.model.ProjectionType;
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;
import com.amazonaws.services.dynamodbv2.model.TableDescription;
import com.amazonaws.services.dynamodbv2.model.UpdateTableRequest;
/**
* Dialog to show the table properties.
*/
public class TablePropertiesDialog extends MessageDialog {
private final String tableName;
private final TableDescription tableDescription;
private Text writeCapacityText;
private Text readCapacityText;
private Long readCapacity;
private Long writeCapacity;
protected TablePropertiesDialog(String tableName) {
super(Display.getCurrent().getActiveShell(), "Table properties for " + tableName, AwsToolkitCore.getDefault().getImageRegistry()
.get(AwsToolkitCore.IMAGE_AWS_ICON), null,
MessageDialog.NONE, new String[] { "Update", "Cancel" }, 1);
this.tableName = tableName;
tableDescription = AwsToolkitCore.getClientFactory().getDynamoDBV2Client()
.describeTable(new DescribeTableRequest().withTableName(tableName)).getTable();
readCapacity = tableDescription.getProvisionedThroughput().getReadCapacityUnits();
writeCapacity = tableDescription.getProvisionedThroughput().getWriteCapacityUnits();
setShellStyle(getShellStyle() | SWT.RESIZE);
}
public UpdateTableRequest getUpdateRequest() {
return new UpdateTableRequest().withTableName(tableName).withProvisionedThroughput(
new ProvisionedThroughput().withReadCapacityUnits(readCapacity).withWriteCapacityUnits(writeCapacity));
}
@Override
protected Control createCustomArea(Composite parent) {
Composite comp = new Composite(parent, SWT.NONE);
GridDataFactory.fillDefaults().grab(true, true).applyTo(comp);
GridLayoutFactory.fillDefaults().numColumns(2).applyTo(comp);
newLabel(comp).setText("Created on:");
newReadOnlyTextField(comp).setText(tableDescription.getCreationDateTime().toString());
newLabel(comp).setText("Status:");
newReadOnlyTextField(comp).setText(tableDescription.getTableStatus());
newLabel(comp).setText("Item count:");
newReadOnlyTextField(comp).setText(tableDescription.getItemCount().toString());
newLabel(comp).setText("Size (bytes):");
newReadOnlyTextField(comp).setText(tableDescription.getTableSizeBytes().toString());
newLabel(comp).setText("Hash key attribute:");
newReadOnlyTextField(comp).setText(getHashKeyName());
newLabel(comp).setText("Hash key type:");
newReadOnlyTextField(comp).setText(getAttributeType(getHashKeyName()));
if ( getRangeKeyName() != null ) {
new Label(comp, SWT.READ_ONLY).setText("Range key attribute:");
newReadOnlyTextField(comp).setText(getRangeKeyName());
new Label(comp, SWT.READ_ONLY).setText("Range key type:");
newReadOnlyTextField(comp).setText(getAttributeType(getRangeKeyName()));
}
new Label(comp, SWT.READ_ONLY).setText("Read capacity units:");
readCapacityText = newTextField(comp);
readCapacityText.setText(readCapacity.toString());
readCapacityText.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
try {
readCapacity = Long.parseLong(readCapacityText.getText());
} catch ( NumberFormatException e1 ) {
readCapacity = null;
}
validate();
}
});
new Label(comp, SWT.READ_ONLY).setText("Write capacity units:");
writeCapacityText = newTextField(comp);
writeCapacityText.setText(writeCapacity.toString());
writeCapacityText.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
try {
writeCapacity = Long.parseLong(writeCapacityText.getText());
} catch ( NumberFormatException e1 ) {
writeCapacity = null;
}
validate();
}
});
if ( tableDescription.getProvisionedThroughput().getLastIncreaseDateTime() != null ) {
new Label(comp, SWT.READ_ONLY).setText("Provisioned throughput last increased:");
newReadOnlyTextField(comp).setText(
tableDescription.getProvisionedThroughput().getLastIncreaseDateTime().toString());
}
if ( tableDescription.getProvisionedThroughput().getLastDecreaseDateTime() != null ) {
new Label(comp, SWT.READ_ONLY).setText("Provisioned throughput last decreased:");
newReadOnlyTextField(comp).setText(
tableDescription.getProvisionedThroughput().getLastDecreaseDateTime().toString());
}
// Local secondary index
Group group = new Group(comp, SWT.NONE);
group.setText("Local Secondary Index");
group.setLayout(new GridLayout(1, false));
GridDataFactory.fillDefaults().grab(true, true).span(2, SWT.DEFAULT).applyTo(group);
IndexTable table = new IndexTable(group);
GridDataFactory.fillDefaults().grab(true, true).applyTo(table);
table.refresh();
return comp;
}
@Override
protected void createButtonsForButtonBar(Composite parent) {
super.createButtonsForButtonBar(parent);
validate();
}
private Text newTextField(Composite comp) {
Text text = new Text(comp, SWT.BORDER);
GridDataFactory.fillDefaults().grab(true, false).applyTo(text);
return text;
}
private Text newReadOnlyTextField(Composite comp) {
Text text = new Text(comp, SWT.READ_ONLY);
text.setBackground(comp.getBackground());
GridDataFactory.fillDefaults().grab(true, false).applyTo(text);
return text;
}
private Label newLabel(Composite comp) {
Label label = new Label(comp, SWT.NONE);
GridDataFactory.fillDefaults().grab(true, false).applyTo(label);
return label;
}
private void validate() {
if ( readCapacity == null || readCapacity < 5 ) {
setErrorMessage("Please enter a read capacity of 5 or more.");
return;
}
if ( writeCapacity == null || writeCapacity < 5 ) {
setErrorMessage("Please enter a write capacity of 5 or more.");
return;
}
setErrorMessage(null);
}
private void setErrorMessage(String message) {
getButton(0).setEnabled(message == null);
}
private String getHashKeyName() {
for (KeySchemaElement element : tableDescription.getKeySchema()) {
if (element.getKeyType().equals(KeyType.HASH.toString())) {
return element.getAttributeName();
}
}
return null;
}
private String getRangeKeyName() {
for (KeySchemaElement element : tableDescription.getKeySchema()) {
if (element.getKeyType().equals(KeyType.RANGE.toString())) {
return element.getAttributeName();
}
}
return null;
}
private String getAttributeType(String attributeName) {
for (AttributeDefinition definition : tableDescription.getAttributeDefinitions()) {
if (definition.getAttributeName().equals(attributeName)) {
return definition.getAttributeType();
}
}
return null;
}
// The table to show the local secondary index info
private class IndexTable extends Composite {
private TableViewer viewer;
private IndexTableContentProvider contentProvider;
private IndexTableLabelProvider labelProvider;
IndexTable(Composite parent) {
super(parent, SWT.NONE);
TableColumnLayout tableColumnLayout = new TableColumnLayout();
this.setLayout(tableColumnLayout);
contentProvider = new IndexTableContentProvider();
labelProvider = new IndexTableLabelProvider();
viewer = new TableViewer(this, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
viewer.getTable().setLinesVisible(true);
viewer.getTable().setHeaderVisible(true);
viewer.setLabelProvider(labelProvider);
viewer.setContentProvider(contentProvider);
createColumns(tableColumnLayout, viewer.getTable());
}
// Enforce call getElement method in contentProvider
public void refresh() {
viewer.setInput(new Object());
}
protected final class IndexTableContentProvider extends ArrayContentProvider {
@Override
public void dispose() {
}
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
@Override
public Object[] getElements(Object inputElement) {
if (tableDescription == null || tableDescription.getLocalSecondaryIndexes() == null) {
return new LocalSecondaryIndexDescription[0];
}
return tableDescription.getLocalSecondaryIndexes().toArray();
}
}
protected final class IndexTableLabelProvider implements ITableLabelProvider {
public void addListener(ILabelProviderListener listener) {
}
public void removeListener(ILabelProviderListener listener) {
}
public void dispose() {
}
public boolean isLabelProperty(Object element, String property) {
return false;
}
public Image getColumnImage(Object element, int columnIndex) {
return null;
}
public String getColumnText(Object element, int columnIndex) {
if (element instanceof LocalSecondaryIndexDescription == false)
return "";
LocalSecondaryIndexDescription index = (LocalSecondaryIndexDescription) element;
switch (columnIndex) {
case 0:
return index.getIndexName();
case 1:
String returnString = "";
returnString += index.getKeySchema().get(1).getAttributeName() + " (";
returnString += getAttributeType(index.getKeySchema().get(1).getAttributeName()) + ")";
return returnString;
case 2:
return index.getIndexSizeBytes().toString();
case 3:
return index.getItemCount().toString();
case 4:
return getProjectionAttributes(index);
}
return element.toString();
}
}
// Generate a String has the detail info about projection in this LSI
private String getProjectionAttributes(LocalSecondaryIndexDescription index) {
String returnString = "";
if (index.getProjection().getProjectionType().equals(ProjectionType.ALL.toString())) {
return index.getProjection().getProjectionType();
} else if (index.getProjection().getProjectionType().equals(ProjectionType.INCLUDE.toString())) {
for (String attribute : index.getProjection().getNonKeyAttributes()) {
returnString += attribute + ", ";
}
returnString = returnString.substring(0, returnString.length() - 2);
return returnString;
} else {
returnString += getHashKeyName() + ", ";
if (getRangeKeyName() != null) {
returnString += getRangeKeyName() + ", ";
}
returnString += index.getKeySchema().get(1).getAttributeName();
return returnString;
}
}
private void createColumns(TableColumnLayout columnLayout, Table table) {
createColumn(table, columnLayout, "Index Name");
createColumn(table, columnLayout, "Attribute To Index");
createColumn(table, columnLayout, "Index Size (Bytes)");
createColumn(table, columnLayout, "Item Count");
createColumn(table, columnLayout, "Projected Attributes");
}
private TableColumn createColumn(Table table, TableColumnLayout columnLayout, String text) {
TableColumn column = new TableColumn(table, SWT.NONE);
column.setText(text);
column.setMoveable(true);
columnLayout.setColumnData(column, new ColumnPixelData(150));
return column;
}
}
}