/*
* RHQ Management Platform
* Copyright (C) 2005-2014 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
package org.rhq.coregui.client.inventory.groups.detail.operation.schedule;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.data.Criteria;
import com.smartgwt.client.data.DSCallback;
import com.smartgwt.client.data.DSRequest;
import com.smartgwt.client.data.DSResponse;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.widgets.HTMLFlow;
import com.smartgwt.client.widgets.form.fields.CheckboxItem;
import com.smartgwt.client.widgets.form.fields.FormItem;
import com.smartgwt.client.widgets.form.fields.RadioGroupItem;
import com.smartgwt.client.widgets.form.fields.events.ChangedEvent;
import com.smartgwt.client.widgets.form.fields.events.ChangedHandler;
import com.smartgwt.client.widgets.grid.HoverCustomizer;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;
import org.rhq.core.domain.criteria.GroupOperationHistoryCriteria;
import org.rhq.core.domain.operation.GroupOperationHistory;
import org.rhq.core.domain.operation.OperationHistory;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceCategory;
import org.rhq.core.domain.resource.group.composite.ResourceGroupComposite;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.coregui.client.CoreGUI;
import org.rhq.coregui.client.ImageManager;
import org.rhq.coregui.client.components.form.EnhancedDynamicForm;
import org.rhq.coregui.client.components.sorter.ReorderableList;
import org.rhq.coregui.client.gwt.GWTServiceLookup;
import org.rhq.coregui.client.inventory.common.detail.operation.schedule.AbstractOperationScheduleDetailsView;
import org.rhq.coregui.client.inventory.resource.AncestryUtil;
import org.rhq.coregui.client.inventory.resource.ResourceDatasource;
import org.rhq.coregui.client.util.async.Command;
import org.rhq.coregui.client.util.enhanced.EnhancedVLayout;
import org.rhq.coregui.client.util.message.Message;
import org.rhq.coregui.client.util.message.Message.Severity;
/**
* The details view of the Group Operations>Schedules subtab.
*
* @author Ian Springer
*/
public class GroupOperationScheduleDetailsView extends AbstractOperationScheduleDetailsView {
private static final String FIELD_EXECUTION_MODE = "executionMode";
private static final String EXECUTION_ORDER_PARALLEL = "parallel";
private static final String EXECUTION_ORDER_SEQUENTIAL = "sequential";
private ResourceGroupComposite groupComposite;
private ListGridRecord[] memberResourceRecords;
private EnhancedDynamicForm executionModeForm;
private ReorderableList memberExecutionOrderer;
private GroupOperationHistory operationExample;
private boolean shouldLoadMemberResourcesFromDataSource = false;
public GroupOperationScheduleDetailsView(ResourceGroupComposite groupComposite, int scheduleId) {
super(new GroupOperationScheduleDataSource(groupComposite),
groupComposite.getResourceGroup().getResourceType(), scheduleId);
this.groupComposite = groupComposite;
}
@Override
protected boolean hasControlPermission() {
return this.groupComposite.getResourcePermission().isControl();
}
@Override
protected int getResourceId() {
return -1;
}
@Override
protected OperationHistory getOperationExample() {
return operationExample;
}
@Override
protected void init(final boolean isReadOnly) {
if (isNewRecord()) {
shouldLoadMemberResourcesFromDataSource = true;
}
if (isNewRecord() && getOperationExampleId() != null) {
GroupOperationHistoryCriteria historyCriteria = new GroupOperationHistoryCriteria();
historyCriteria.addFilterId(getOperationExampleId());
historyCriteria.fetchOperationDefinition(true);
historyCriteria.fetchParameters(true);
historyCriteria.setPageControl(PageControl.getSingleRowInstance());
GWTServiceLookup.getOperationService().findGroupOperationHistoriesByCriteria(historyCriteria,
new LoadExampleCallback(new Command() {
@Override
public void execute() {
GroupOperationScheduleDetailsView.super.init(isReadOnly);
}
}));
} else {
super.init(isReadOnly);
}
}
@Override
protected EnhancedVLayout buildContentPane() {
EnhancedVLayout contentPane = super.buildContentPane();
HTMLFlow hr = new HTMLFlow("<hr/>");
contentPane.addMember(hr);
this.executionModeForm = new EnhancedDynamicForm(isReadOnly());
this.executionModeForm.setNumCols(2);
this.executionModeForm.setColWidths(FIRST_COLUMN_WIDTH, "*");
RadioGroupItem executionModeItem = new RadioGroupItem(FIELD_EXECUTION_MODE,
MSG.view_group_operationScheduleDetails_field_execute());
LinkedHashMap<String, String> valueMap = new LinkedHashMap<String, String>(2);
valueMap.put(EXECUTION_ORDER_PARALLEL, MSG.view_group_operationScheduleDetails_value_parallel());
valueMap.put(EXECUTION_ORDER_SEQUENTIAL, MSG.view_group_operationScheduleDetails_value_sequential());
executionModeItem.setValueMap(valueMap);
executionModeItem.setDefaultValue(EXECUTION_ORDER_PARALLEL);
executionModeItem.setShowTitle(true);
final CheckboxItem haltOnFailureItem = new CheckboxItem(GroupOperationScheduleDataSource.Field.HALT_ON_FAILURE,
MSG.view_group_operationScheduleDetails_field_haltOnFailure());
haltOnFailureItem.setDefaultValue(false);
haltOnFailureItem.setVisible(false);
haltOnFailureItem.setLabelAsTitle(true);
haltOnFailureItem.setShowTitle(true);
this.executionModeForm.setFields(executionModeItem, haltOnFailureItem);
contentPane.addMember(this.executionModeForm);
HLayout hLayout = new HLayout();
VLayout horizontalSpacer = new VLayout();
horizontalSpacer.setWidth(140);
hLayout.addMember(horizontalSpacer);
ResourceCategory resourceCategory = this.groupComposite.getResourceGroup().getResourceType().getCategory();
String memberIcon = ImageManager.getResourceIcon(resourceCategory);
HoverCustomizer nameHoverCustomizer = new HoverCustomizer() {
public String hoverHTML(Object value, ListGridRecord listGridRecord, int rowNum, int colNum) {
return AncestryUtil.getAncestryHoverHTML(listGridRecord, 0);
}
};
if (shouldLoadMemberResourcesFromDataSource) {
GroupOperationScheduleResourceDatasource resourceDatasource;
resourceDatasource = new GroupOperationScheduleResourceDatasource();
Criteria criteria = new Criteria(ResourceDatasource.FILTER_GROUP_ID,
String.valueOf(GroupOperationScheduleDetailsView.this.groupComposite.getResourceGroup().getId()));
this.memberExecutionOrderer = new ReorderableList(this.memberResourceRecords, null, memberIcon,
nameHoverCustomizer, resourceDatasource, criteria);
} else {
this.memberExecutionOrderer = new ReorderableList(this.memberResourceRecords, null, memberIcon,
nameHoverCustomizer);
}
this.memberExecutionOrderer.setVisible(false);
this.memberExecutionOrderer.setNameFieldTitle(MSG.view_group_operationScheduleDetails_memberResource());
hLayout.addMember(this.memberExecutionOrderer);
contentPane.addMember(hLayout);
executionModeItem.addChangedHandler(new ChangedHandler() {
public void onChanged(ChangedEvent event) {
if (event.getValue().equals(EXECUTION_ORDER_PARALLEL)) {
haltOnFailureItem.hide();
memberExecutionOrderer.hide();
} else {
haltOnFailureItem.show();
memberExecutionOrderer.show();
}
}
});
return contentPane;
}
@SuppressWarnings("unchecked")
@Override
protected void editExistingRecord(final Record record) {
List<Resource> executionOrder = (List<Resource>) record
.getAttributeAsObject(GroupOperationScheduleDataSource.Field.EXECUTION_ORDER);
if (executionOrder != null) {
Integer[] resourceIds = new Integer[executionOrder.size()];
int i = 0;
for (Resource resource : executionOrder) {
resourceIds[i++] = resource.getId();
}
GroupOperationScheduleResourceDatasource resourceDatasource = new GroupOperationScheduleResourceDatasource();
Criteria criteria = new Criteria();
criteria.addCriteria(ResourceDatasource.FILTER_RESOURCE_IDS, resourceIds);
resourceDatasource.fetchData(criteria, new DSCallback() {
public void execute(DSResponse response, Object rawData, DSRequest request) {
if (response.getStatus() != DSResponse.STATUS_SUCCESS) {
throw new RuntimeException(MSG.view_group_operationScheduleDetails_failedToLoadMembers());
}
Record[] data = response.getData();
ListGridRecord[] resourceRecords = new ListGridRecord[data.length];
for (int i = 0, dataLength = data.length; i < dataLength; i++) {
Record record = data[i];
ListGridRecord listGridRecord = (ListGridRecord) record;
resourceRecords[i] = listGridRecord;
}
executionModeForm.setValue(FIELD_EXECUTION_MODE, EXECUTION_ORDER_SEQUENTIAL);
memberExecutionOrderer.setRecords(resourceRecords);
memberExecutionOrderer.show();
FormItem haltOnFailureItem = executionModeForm
.getField(GroupOperationScheduleDataSource.Field.HALT_ON_FAILURE);
Object haltOnFailure = getForm().getValue(GroupOperationScheduleDataSource.Field.HALT_ON_FAILURE);
haltOnFailureItem.setValue(haltOnFailure);
haltOnFailureItem.show();
GroupOperationScheduleDetailsView.super.editExistingRecord(record);
}
});
} else {
this.executionModeForm.setValue(FIELD_EXECUTION_MODE, EXECUTION_ORDER_PARALLEL);
Object haltOnFailure = getForm().getValue(GroupOperationScheduleDataSource.Field.HALT_ON_FAILURE);
FormItem haltOnFailureItem = this.executionModeForm
.getField(GroupOperationScheduleDataSource.Field.HALT_ON_FAILURE);
haltOnFailureItem.setValue(haltOnFailure);
super.editExistingRecord(record);
}
}
@Override
protected void save(DSRequest requestProperties) {
String executionMode = this.executionModeForm.getValueAsString(FIELD_EXECUTION_MODE);
List<Resource> executionOrder;
if (executionMode.equals(EXECUTION_ORDER_SEQUENTIAL)) {
ListGridRecord[] resourceRecords = this.memberExecutionOrderer.getRecords();
ResourceDatasource resourceDatasource = new ResourceDatasource();
Set<Resource> resources = resourceDatasource.buildDataObjects(resourceRecords);
executionOrder = new ArrayList<Resource>(resources);
} else {
executionOrder = null;
}
requestProperties
.setAttribute(GroupOperationScheduleDataSource.RequestProperty.EXECUTION_ORDER, executionOrder);
Boolean haltOnFailure = (Boolean) this.executionModeForm
.getValue(GroupOperationScheduleDataSource.Field.HALT_ON_FAILURE);
getForm().setValue(GroupOperationScheduleDataSource.Field.HALT_ON_FAILURE, haltOnFailure);
super.save(requestProperties);
}
private class LoadExampleCallback implements AsyncCallback<PageList<GroupOperationHistory>> {
private Command command;
public LoadExampleCallback(Command command) {
this.command = command;
}
@Override
public void onFailure(Throwable throwable) {
CoreGUI.getMessageCenter().notify(
new Message(MSG.view_operationScheduleDetails_load_example_failure(), throwable, Severity.Warning));
command.execute();
}
@Override
public void onSuccess(PageList<GroupOperationHistory> groupOperationHistories) {
if (groupOperationHistories.getTotalSize() == 0) {
CoreGUI.getMessageCenter().notify(
new Message(MSG.view_operationScheduleDetails_example_not_found(), Severity.Warning));
} else if (groupOperationHistories.getTotalSize() != 1) {
CoreGUI.getMessageCenter().notify(
new Message(MSG.view_operationScheduleDetails_example_not_unique(), Severity.Warning));
} else {
operationExample = groupOperationHistories.get(0);
}
command.execute();
}
}
}