/*
* Lokomo OneCMDB - An Open Source Software for Configuration
* Management of Datacenter Resources
*
* Copyright (C) 2006 Lokomo Systems AB
*
* 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; either version 2 of the License, or (at
* your option) any later version.
*
* 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.
*
* Lokomo Systems AB can be contacted via e-mail: info@lokomo.com or via
* paper mail: Lokomo Systems AB, Sv�rdv�gen 27, SE-182 33
* Danderyd, Sweden.
*
*/
package org.onecmdb.ui.gwt.desktop.client.window.model;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.onecmdb.ui.gwt.desktop.client.WindowFactory;
import org.onecmdb.ui.gwt.desktop.client.action.CloseTextToolItem;
import org.onecmdb.ui.gwt.desktop.client.mvc.CMDBEvents;
import org.onecmdb.ui.gwt.desktop.client.service.CMDBAsyncCallback;
import org.onecmdb.ui.gwt.desktop.client.service.content.Config;
import org.onecmdb.ui.gwt.desktop.client.service.content.ContentData;
import org.onecmdb.ui.gwt.desktop.client.service.content.ContentFile;
import org.onecmdb.ui.gwt.desktop.client.service.content.ContentFolder;
import org.onecmdb.ui.gwt.desktop.client.service.model.AliasFactory;
import org.onecmdb.ui.gwt.desktop.client.service.model.CIModel;
import org.onecmdb.ui.gwt.desktop.client.service.model.CMDBDesktopWindowItem;
import org.onecmdb.ui.gwt.desktop.client.service.model.CMDBSession;
import org.onecmdb.ui.gwt.desktop.client.service.model.ModelItem;
import org.onecmdb.ui.gwt.desktop.client.service.model.ModelServiceFactory;
import org.onecmdb.ui.gwt.desktop.client.service.model.StoreResult;
import org.onecmdb.ui.gwt.desktop.client.service.model.ValueListModel;
import org.onecmdb.ui.gwt.desktop.client.service.model.ValueModel;
import org.onecmdb.ui.gwt.desktop.client.service.model.mdr.MDRHistoryState;
import org.onecmdb.ui.gwt.desktop.client.utils.CIModelUtils;
import org.onecmdb.ui.gwt.desktop.client.widget.CompareGridWidget;
import org.onecmdb.ui.gwt.desktop.client.widget.ContentSelectorWidget;
import org.onecmdb.ui.gwt.desktop.client.window.CMDBAbstractWidget;
import org.onecmdb.ui.gwt.desktop.client.window.WidgetDescription;
import com.extjs.gxt.ui.client.Style.LayoutRegion;
import com.extjs.gxt.ui.client.Style.Scroll;
import com.extjs.gxt.ui.client.Style.SelectionMode;
import com.extjs.gxt.ui.client.data.BaseModel;
import com.extjs.gxt.ui.client.event.BaseEvent;
import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.util.Margins;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.DataList;
import com.extjs.gxt.ui.client.widget.DataListItem;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.Window;
import com.extjs.gxt.ui.client.widget.button.ToolButton;
import com.extjs.gxt.ui.client.widget.layout.BorderLayout;
import com.extjs.gxt.ui.client.widget.layout.BorderLayoutData;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.layout.RowData;
import com.extjs.gxt.ui.client.widget.layout.RowLayout;
import com.extjs.gxt.ui.client.widget.menu.Menu;
import com.extjs.gxt.ui.client.widget.menu.MenuItem;
import com.extjs.gxt.ui.client.widget.toolbar.FillToolItem;
import com.extjs.gxt.ui.client.widget.toolbar.SeparatorToolItem;
import com.extjs.gxt.ui.client.widget.toolbar.TextToolItem;
import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
import com.extjs.gxt.ui.client.widget.toolbar.ToolItem;
import com.extjs.gxt.ui.client.widget.tree.TreeItem;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.HTML;
public class CMDBImportModelWindow extends CMDBAbstractWidget {
public static final String ID = "cmdb-model-import";
private CIModel mdrRepository;
private CIModel mdrConfig;
private ContentSelectorWidget storedTree;
//private DataList storeList;
//private CIModel mdrConfigBase;
public CMDBImportModelWindow(CMDBDesktopWindowItem item) {
super(item);
}
public ContentFile getMDR() {
ContentFile mdr = new ContentFile();
String mdrConf = item.getParams().get("mdrConfig");
if (mdrConf == null) {
mdrConf = CMDBSession.get().getConfig().get(Config.OneCMDBWebService);
}
mdr.setPath(mdrConf);
return(mdr);
}
@Override
protected void onRender(Element parent, int index) {
super.onRender(parent, index);
// Load modelMDR and modelConfig...
ModelServiceFactory.get().loadModelMDRInfo(CMDBSession.get().getToken(), item.getParams(), new CMDBAsyncCallback<BaseModel>() {
public void onSuccess(BaseModel result) {
mdrRepository = result.get("mdr");
mdrConfig = result.get("mdrConfig");
//mdrConfigBase = mdrConfig.copy();
init();
}
});
}
protected void init() {
setLayout(new RowLayout());
ContentFolder root = new ContentFolder();
root.setPath((String)item.getParams().get("modelRoot"));
final ContentSelectorWidget browser = new ContentSelectorWidget(root);
/*
ValueListModel contentFiles = (ValueListModel) mdrConfig.getValue("modelFiles");
if (contentFiles != null) {
List<ContentData> selected = new ArrayList<ContentData>();
for (ValueModel vModel : contentFiles.getValues()) {
if (vModel.getValue() == null) {
continue;
}
ContentFile data = new ContentFile();
data.setPath(vModel.getValue());
selected.add(data);
}
//browser.setSelected(selected);
}
*/
browser.setSelected(new ArrayList<ContentData>());
/*
final CompareGridWidget compare = new CompareGridWidget();
compare.setRejectEnabled(false);
compare.setDeleteEnabled(false);
*/
ContentPanel browserCp = new ContentPanel();
browserCp.setHeading("Select Models to import");
browserCp.setLayoutOnChange(true);
browserCp.setLayout(new FitLayout());
browserCp.setScrollMode(Scroll.AUTO);
browserCp.add(browser);
ContentPanel storedModels = new ContentPanel();
storedModels.setHeading("Imported Models");
storedTree = new ContentSelectorWidget(root);
//storeList = new DataList();
//storeList.setScrollMode(Scroll.AUTO);
//storeList.setSelectionMode(SelectionMode.MULTI);
storedModels.setLayout(new FitLayout());
storedModels.add(storedTree);
updateStoredDataList();
Menu undoMenu = new Menu();
MenuItem undoImport = new MenuItem("Remove", "reject-icon");
undoImport.setToolTip("Remove the selected imported Model File from the CMDB");
undoImport.addSelectionListener(new SelectionListener<ComponentEvent>() {
@Override
public void componentSelected(ComponentEvent ce) {
List<TreeItem> items = storedTree.getTree().getSelectedItems();
if (items.size() == 0) {
return;
}
List<String> result = getCurrentModels();
for (TreeItem item : items) {
if (!(item.getModel() instanceof ContentFile)) {
continue;
}
ContentData data = (ContentData)item.getModel();
result.remove(data.getPath());
}
openCompareWindow(result, true);
}
});
undoMenu.add(undoImport);
storedTree.setContextMenu(undoMenu);
storedModels.getHeader().addTool(new ToolButton("x-tool-plus", new SelectionListener<ComponentEvent>() {
@Override
public void componentSelected(ComponentEvent ce) {
storedTree.expandAll();
}
}));
storedModels.getHeader().addTool(new ToolButton("x-tool-minus", new SelectionListener<ComponentEvent>() {
@Override
public void componentSelected(ComponentEvent ce) {
storedTree.collapseAll();
}
}));
browserCp.getHeader().addTool(new ToolButton("x-tool-plus", new SelectionListener<ComponentEvent>() {
@Override
public void componentSelected(ComponentEvent ce) {
browser.expandAll();
}
}));
browserCp.getHeader().addTool(new ToolButton("x-tool-minus", new SelectionListener<ComponentEvent>() {
@Override
public void componentSelected(ComponentEvent ce) {
browser.collapseAll();
}
}));
/*
ContentPanel compareCp = new ContentPanel();
compareCp.setHeading("Status of selected models");
compareCp.setScrollMode(Scroll.AUTO);
compareCp.setLayout(new FitLayout());
compareCp.add(compare);
*/
/*
BorderLayoutData west = new BorderLayoutData(LayoutRegion.WEST, 300);
west.setSplit(true);
west.setCollapsible(true);
west.setMargins(new Margins(5));
*/
/*
TextToolItem cancel = new TextToolItem("Close", "cancel-icon");
cancel.setToolTip("Close this window");
cancel.addSelectionListener(new SelectionListener<ComponentEvent>() {
@Override
public void componentSelected(ComponentEvent ce) {
if (getParent() instanceof Window) {
((Window)getParent()).close();
}
}
});
*/
ToolBar deleteBar = new ToolBar();
TextToolItem deleteTool = new TextToolItem("Remove", "delete-icon");
deleteTool.setToolTip("Remove the selected imported Model File from the CMDB");
deleteTool.addSelectionListener(new SelectionListener<ComponentEvent>() {
@Override
public void componentSelected(ComponentEvent ce) {
List<TreeItem> items = storedTree.getTree().getSelectedItems();
if (items.size() == 0) {
return;
}
List<String> result = getCurrentModels();
for (TreeItem item : items) {
if (!(item.getModel() instanceof ContentFile)) {
continue;
}
ContentData data = (ContentData)item.getModel();
result.remove(data.getPath());
}
openCompareWindow(result, true);
}
});
deleteBar.add(new FillToolItem());
deleteBar.add(deleteTool);
deleteBar.add(new SeparatorToolItem());
deleteBar.add(new CloseTextToolItem(this));
ToolBar bar = new ToolBar();
TextToolItem openTool = new TextToolItem("Open", "compare-icon");
openTool.setToolTip("Open and verify the selected model files");
openTool.addSelectionListener(new SelectionListener<ComponentEvent>() {
@Override
public void componentSelected(ComponentEvent ce) {
List<ContentData> items = browser.getSelected();
/*
if (items.size() == 0) {
MessageBox.info("Info", "Nothing selected", null);
return;
}
*/
List<String> result = new ArrayList<String>();
for (ContentData item : items) {
if (item instanceof ContentFile) {
result.add(item.getPath());
}
}
// Compare if we have them already.
ValueModel files = mdrConfig.getValue("modelFiles");
if (files instanceof ValueListModel) {
for (ValueModel v : ((ValueListModel)files).getValues()) {
if (v.getValue() == null || v.getValue().length() == 0) {
continue;
}
if (!result.contains(v.getValue())) {
result.add(v.getValue());
}
}
}
openCompareWindow(result, false);
//compare.setModels(mdrRepository, mdrConfig, history);
}
});
//browserCp.getHeader().addTool(compareTool);
bar.add(new FillToolItem());
bar.add(openTool);
bar.add(new SeparatorToolItem());
//bar.add(cancel);
bar.add(new FillToolItem());
StringBuffer b = new StringBuffer();
b.append("<p>");
b.append("<b>Info</b></br>Select Model Files that shall be imported to the CMDB.<br/>");
b.append("The selected Model Files will be compared to the current Models in the CMDB before the new Models are committed to the CMDB<br/>");
b.append("Warning: If you remove an imported Model, all instances derived from Templates in this Model will also be removed (deleted).<br/>");
b.append("</p>");
b.append("<p>");
b.append("<i>Note: All imported models will be checked for changes</i><br>");
b.append("</p>");
HTML html = new HTML(b.toString());
html.setStyleName("property-panel-background");
add(html, new RowData(1,-1));
ContentPanel center = new ContentPanel();
center.setLayout(new BorderLayout());
center.setHeaderVisible(false);
BorderLayoutData centerData = new BorderLayoutData(LayoutRegion.CENTER);
centerData.setMargins(new Margins(5, 0, 5, 0));
BorderLayoutData eastData = new BorderLayoutData(LayoutRegion.EAST, 450);
eastData.setSplit(true);
eastData.setCollapsible(false);
eastData.setMargins(new Margins(5));
//center.setBottomComponent(bar);
browserCp.setBottomComponent(bar);
storedModels.setBottomComponent(deleteBar);
center.add(browserCp, centerData);
center.add(storedModels, eastData);
add(center, new RowData(1,1));
//add(compareCp, new BorderLayoutData(LayoutRegion.CENTER));
layout();
}
private void updateStoredDataList() {
Set<ContentData> includeSet = new HashSet<ContentData>();
for (String file : getCurrentModels()) {
ContentData data = new ContentData();
data.setPath(file);
includeSet.add(data);
appendParent(data.getParent(), includeSet);
}
storedTree.setIncludeSet(includeSet);
storedTree.reload();
}
protected List<String> getCurrentModels() {
//storeList.removeAll();
ValueModel files = mdrConfig.getValue("modelFiles");
List<String> result = new ArrayList<String>();
if (files instanceof ValueListModel) {
for (ValueModel v : ((ValueListModel)files).getValues()) {
if (v.getValue() == null || v.getValue().length() == 0) {
continue;
}
result.add(v.getValue());
}
}
return(result);
}
private void appendParent(ContentData parent, Set<ContentData> includeSet) {
if (parent == null) {
return;
}
includeSet.add(parent);
appendParent(parent.getParent(), includeSet);
}
protected void openCompareWindow(final List<String> result, boolean delete) {
final CIModel history = new CIModel();
history.setDerivedFrom(MDRHistoryState.getHistoryTemplate());
CIModelUtils.updateModel(history, "files", result);
CIModelUtils.updateModel(history, "mdrConfigEntry", mdrConfig.getAlias(), true);
history.setAlias(AliasFactory.generateAlias(MDRHistoryState.getHistoryTemplate()));
CompareGridWidget compare = new CompareGridWidget();
compare.addListener(CMDBEvents.COMMIT_EVENT, new Listener<BaseEvent>() {
public void handleEvent(BaseEvent be) {
final MessageBox info = MessageBox.wait("Update", "Updating", "Wait...");
ModelServiceFactory.get().loadModelMDRInfo(CMDBSession.get().getToken(), item.getParams(), new CMDBAsyncCallback<BaseModel>() {
@Override
public void onFailure(Throwable t) {
info.close();
super.onFailure(t);
}
public void onSuccess(BaseModel m) {
mdrRepository = m.get("mdr");
mdrConfig = m.get("mdrConfig");
CIModel mdrConfigBase = mdrConfig.copy();
ValueListModel list = new ValueListModel();
list.setAlias("modelFiles");
for (String value : result) {
ValueModel v = new ValueModel();
v.setValue(value);
v.setIsComplex(false);
v.setAlias("modelFiles");
list.addValue(v);
}
mdrConfig.setValue("modelFiles", list);
List<ModelItem> local = new ArrayList<ModelItem>();
List<ModelItem> base = new ArrayList<ModelItem>();
local.add(mdrConfig);
base.add(mdrConfigBase);
// Update CMDB.
ModelServiceFactory.get().store(getMDR(), CMDBSession.get().getToken(), local, base, new CMDBAsyncCallback<StoreResult>() {
@Override
public void onFailure(Throwable t) {
info.close();
super.onFailure(t);
}
@Override
public void onSuccess(StoreResult arg0) {
info.close();
if (arg0.isRejected()) {
MessageBox.alert("Error", "Can't store information about committed models, " + arg0.getRejectCause(), null);
return;
}
updateStoredDataList();
}
});
}
});
}
});
String title = "Compare selected models with previously imported models";
if (delete) {
title = "Remove previously imported models";
}
Window w = WindowFactory.getWindow(title, compare);
w.show();
compare.setModels(mdrRepository, mdrConfig, history);
}
@Override
public WidgetDescription getDescription() {
WidgetDescription desc = new WidgetDescription();
desc.setId(ID);
desc.setName("Open OneCMDB Models");
desc.setDescription("Open OneCMDB model data. The model can contain template/instances/references");
desc.addParameter("modelRoot - Path to where models are keept");
return(desc);
}
}