/*
Copyright (C) 2003 EBI, GRL
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.ensembl.mart.editor;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.io.File;
import java.net.URL;
import java.util.List;
import javax.swing.ImageIcon;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JTree;
import javax.swing.event.InternalFrameEvent;
import javax.swing.event.InternalFrameListener;
import javax.swing.tree.DefaultTreeCellRenderer;
import org.ensembl.mart.lib.config.AttributeCollection;
import org.ensembl.mart.lib.config.AttributeDescription;
import org.ensembl.mart.lib.config.AttributeGroup;
import org.ensembl.mart.lib.config.AttributeList;
import org.ensembl.mart.lib.config.AttributePage;
import org.ensembl.mart.lib.config.BaseConfigurationObject;
import org.ensembl.mart.lib.config.ConfigurationException;
import org.ensembl.mart.lib.config.DSConfigAdaptor;
import org.ensembl.mart.lib.config.DatabaseDSConfigAdaptor;
import org.ensembl.mart.lib.config.DatasetConfig;
import org.ensembl.mart.lib.config.DatasetConfigIterator;
import org.ensembl.mart.lib.config.DynamicDataset;
import org.ensembl.mart.lib.config.Exportable;
import org.ensembl.mart.lib.config.FilterCollection;
import org.ensembl.mart.lib.config.FilterDescription;
import org.ensembl.mart.lib.config.FilterGroup;
import org.ensembl.mart.lib.config.FilterPage;
import org.ensembl.mart.lib.config.Importable;
import org.ensembl.mart.lib.config.Option;
import org.ensembl.mart.lib.config.SimpleDSConfigAdaptor;
import org.ensembl.mart.lib.config.URLDSConfigAdaptor;
import org.jdom.Document;
/**
* DatasetConfigTreeWidget extends internal frame.
*
*
* @author <a href="mailto:katerina@ebi.ac.uk">Katerina Tzouvara</a>
* //@see org.ensembl.mart.config.DatasetConfig
*/
public class DatasetConfigTreeWidget extends JInternalFrame{
private DatasetConfig datasetConfig = null;
private DatasetConfigTree naiveTree = null;
private static int openFrameCount = 0;
private static final int xOffset = 10, yOffset = 10;
private JDesktopPane desktop;
private GridBagConstraints constraints;
private DatasetConfigTree tree;
private File file = null;
private MartEditor editor;
public DatasetConfigTreeWidget(File file, MartEditor editor, DatasetConfig dsv, String user,
String dataset, String datasetID, String schema, String template, String settingsFlag){
super("Dataset Tree " + (++openFrameCount),
true, //resizable
true, //closable
true, //maximizable
true);//iconifiable
this.editor = editor;
this.setDefaultCloseOperation(JInternalFrame.DO_NOTHING_ON_CLOSE);
this.addInternalFrameListener(new CloseListener());
try {
DatasetConfig config = null;
if (dsv == null){
if (file == null) {
if (user == null){
if (schema == null){
config = new DatasetConfig("new", "new", "new");
config.setDSConfigAdaptor(new SimpleDSConfigAdaptor(config)); //prevents lazyLoading
config.addFilterPage(new FilterPage("new"));
config.addAttributePage(new AttributePage("new"));
}
else{// naive
config = MartEditor.getDatabaseDatasetConfigUtils().getNaiveDatasetConfigFor(schema,dataset);
config.setDSConfigAdaptor(new SimpleDSConfigAdaptor(config)); //prevents lazyLoading
if (config.getFilterPages().length+config.getAttributePages().length==0) {
JOptionPane.showMessageDialog(null,"No usable tables were found.");
return;
}
if (config.getPrimaryKeys().length == 0 || !config.getPrimaryKeys()[0].toLowerCase().endsWith("_key")){
JOptionPane.showMessageDialog(null,"Your main table must contain a primary key ending _key");
return;
}
config.setTemplate(template);
DatasetConfigAttributesTable attrTable = new DatasetConfigAttributesTable(
config, this);
tree = new DatasetConfigTree(config,
this, attrTable);
setNaiveTree(tree);
// THEN JUST OPEN UP TEMPLATE DOC
DatasetConfig templateConfig = new DatasetConfig("template","",template+"_template","","","","","","","","","","","",template,"","","","");
Document templateDocument = MartEditor.getDatabaseDatasetConfigUtils().getTemplateDocument(template);
if (templateDocument==null) {
templateConfig = new DatasetConfig(config,true,false);
// Generate template document based on existing config.
templateConfig.setInternalName("template");
templateConfig.setDataset(template+"_template");
templateConfig.setTemplate(template);
} else {
MartEditor.getDatasetConfigXMLUtils().loadDatasetConfigWithDocument(templateConfig, templateDocument);
// first of all call getNewFiltsAtts so any extra atts in a new config get added to the template
templateConfig = MartEditor.getDatabaseDatasetConfigUtils().getNewFiltsAtts(schema,config,false);
}
if (templateConfig.getDynamicDataset(dataset)==null)
templateConfig.addDynamicDataset(new DynamicDataset(dataset,null));
templateConfig.setTemplateFlag("1");
config = templateConfig;
//int templateCount = MartEditor.getDatabaseDatasetConfigUtils().templateCount(template);
//if (templateCount > 0)
// config = MartEditor.getDatabaseDatasetConfigUtils().updateConfigToTemplate(config,0);
}
}
else{//Importing config
if (template != null){
// import template
//config = MartEditor.getDatabaseDatasetConfigUtils().getTemplateConfig(template);
DatasetConfig templateConfig = new DatasetConfig("template","",template+"_template","","","","","","","","","","","",template,"","","","");
Document templateDocument = MartEditor.getDatabaseDatasetConfigUtils().getTemplateDocument(template);
MartEditor.getDatasetConfigXMLUtils().loadDatasetConfigWithDocument(templateConfig, templateDocument);
templateConfig.setTemplateFlag("1");
config = templateConfig;
}
else if (settingsFlag == null){
// have an indiviudal config just for read-only viewing
DSConfigAdaptor adaptor = new DatabaseDSConfigAdaptor(MartEditor.getDetailedDataSource(),user, "", true, false, true, true);
DatasetConfigIterator configs = adaptor.getDatasetConfigs();
while (configs.hasNext()){
DatasetConfig lconfig = (DatasetConfig) configs.next();
if (lconfig.getDataset().equals(dataset) && lconfig.getDatasetID().equals(datasetID)){
config = lconfig;
break;
}
}
}
else{
// have an individual config without a template - generate template
DSConfigAdaptor adaptor = new DatabaseDSConfigAdaptor(MartEditor.getDetailedDataSource(),user, "", true, false, true, false);
DatasetConfigIterator configs = adaptor.getDatasetConfigs();
while (configs.hasNext()){
DatasetConfig lconfig = (DatasetConfig) configs.next();
if (lconfig.getDataset().equals(dataset) && lconfig.getDatasetID().equals(datasetID)){
config = lconfig;
break;
}
}
//System.out.println("GOT IMPORTED CONFIG WITH TEMPLATE "+config.getTemplate());
// convert config to latest version using xslt - ? whether to do
config = MartEditor.getDatabaseDatasetConfigUtils().getXSLTransformedConfig(config);
// now just create a template with same name as dataset and open up
// if want to change to a more generic n1 template use the Set template option
if (settingsFlag.equals("1")){
template = dataset;
}
else if (settingsFlag.equals("0")){// the set template option
// CHOOSE A TEMPLATE AS FOR NAIVE GENERATION
int choice = JOptionPane.showConfirmDialog(null,"Create new template rather than use existing one?");
if (choice == 0){// YES
template = (String) JOptionPane.showInputDialog(null,"New template name",dataset);
}
else if (choice == 1){// NO
String[] templates = MartEditor.getDatabaseDatasetConfigUtils().getAllTemplateNames();
if(templates.length!=0){
template =
(String) JOptionPane.showInputDialog(
null,
"Choose one",
"Template",
JOptionPane.INFORMATION_MESSAGE,
null,
templates,null);
if (template == null)
return;
}
else{
JOptionPane.showMessageDialog(null,"No existing templates available. Create a new one");
return;
}
}
else{// CANCEL
return;
}
}
config.setTemplate(template);
DatasetConfigAttributesTable attrTable = new DatasetConfigAttributesTable(
config, this);
tree = new DatasetConfigTree(config,
this, attrTable);
setNaiveTree(tree);
// THEN JUST OPEN UP TEMPLATE DOC
DatasetConfig templateConfig = new DatasetConfig("template","",template+"_template","","","","","","","","","","","",template,"","","","");
Document templateDocument = MartEditor.getDatabaseDatasetConfigUtils().getTemplateDocument(template);
if (templateDocument==null) {
templateConfig = new DatasetConfig(config,true,false);
// Generate template document based on existing config.
templateConfig.setInternalName("template");
templateConfig.setDataset(template+"_template");
templateConfig.setTemplate(template);
// Convert tableConstraint names.
MartEditor.getDatabaseDatasetConfigUtils().stripTableConstraints(templateConfig);
}
else {
MartEditor.getDatasetConfigXMLUtils().loadDatasetConfigWithDocument(templateConfig, templateDocument);
}
if (templateConfig.getDynamicDataset(dataset)==null)
templateConfig.addDynamicDataset(new DynamicDataset(dataset,null));
templateConfig.setTemplateFlag("1");
config = templateConfig;
}
}
}
else {// open from file
URL url = file.toURL();
// ignore cache, include hidden members
DSConfigAdaptor adaptor = new URLDSConfigAdaptor(url,true, true);
// only config one in the file so get that one
config = (DatasetConfig) adaptor.getDatasetConfigs().next();
config.setDatasetID("");//always blank from file so gets sorted out by database during export
if (config.getTemplate() == null || config.getTemplate().equals(""))
config.setTemplate(config.getDataset());
}
}// end of dsv = null
else{
config = new DatasetConfig(dsv, true, false);
}
// convert config to latest version using xslt - COMMENTED OUT AS WAS TRANSFORMING TEMPLATE AND
// CAUSING MEMORY ERRORS - ? IF NEEED THOUGH
//config = MartEditor.getDatabaseDatasetConfigUtils().getXSLTransformedConfig(config);
this.setTitle(schema + "." + config.getDataset());
JFrame.setDefaultLookAndFeelDecorated(true);
DatasetConfigAttributesTable attrTable = new DatasetConfigAttributesTable(
config, this);
tree = new DatasetConfigTree(config,
this, attrTable);
tree.setCellRenderer(new MyRenderer());
// for update
setDatasetConfig(config);
JScrollPane treeScrollPane = new JScrollPane(tree);
JScrollPane tableScrollPane = new JScrollPane(attrTable);
JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
treeScrollPane, tableScrollPane);
splitPane.setOneTouchExpandable(true);
splitPane.setDividerLocation(350);
//Provide minimum sizes for the two components in the split pane.
Dimension minimumSize = new Dimension(350, 450);
treeScrollPane.setMinimumSize(minimumSize);
tableScrollPane.setMinimumSize(minimumSize);
this.getContentPane().add(splitPane);
//...Then set the window size or call pack...
setSize(800, 400);
// SHOULD BE ABLE TO GET RID OF BELOW
//int templateCount = MartEditor.getDatabaseDatasetConfigUtils().templateCount(config.getTemplate());
if (template == null){// && templateCount > 1){// flag non-template XMLs with a template origin
//JOptionPane.showMessageDialog(null,"This config is under template control. You need to edit the template in the majority of cases");
Importable[] imps = config.getImportables();
for (int i = 0; i < imps.length; i++){
imps[i].setTemplateDrivenFlag(1);
}
Exportable[] exps = config.getExportables();
for (int i = 0; i < exps.length; i++){
exps[i].setTemplateDrivenFlag(1);
}
FilterPage[] fpages = config.getFilterPages();
for (int i = 0; i < fpages.length; i++){
FilterPage fpage = fpages[i];
fpage.setTemplateDrivenFlag(1);
List fgroups = fpage.getFilterGroups();
for (int j = 0; j < fgroups.size(); j++){
FilterGroup fgroup = (FilterGroup) fgroups.get(j);
fgroup.setTemplateDrivenFlag(1);
FilterCollection[] fcolls = fgroup.getFilterCollections();
for (int k = 0; k < fcolls.length; k++){
FilterCollection fcoll = fcolls[k];
fcoll.setTemplateDrivenFlag(1);
List fds = fcoll.getFilterDescriptions();
for (int l = 0; l < fds.size(); l++){
FilterDescription fd = (FilterDescription) fds.get(l);
if (!fd.getInternalName().matches("\\w+\\.\\w+")
&& !fd.getInternalName().matches("\\w+\\.\\w+\\.\\w+"))
fd.setTemplateDrivenFlag(1);
Option[] ops = fd.getOptions();
for (int m = 0; m < ops.length; m++){
Option op = ops[m];
if (op.getTableConstraint() != null)
op.setTemplateDrivenFlag(1);
}
}
}
}
}
AttributePage[] apages = config.getAttributePages();
for (int i = 0; i < apages.length; i++){
AttributePage apage = apages[i];
apage.setTemplateDrivenFlag(1);
List agroups = apage.getAttributeGroups();
for (int j = 0; j < agroups.size(); j++){
AttributeGroup agroup = (AttributeGroup) agroups.get(j);
agroup.setTemplateDrivenFlag(1);
AttributeCollection[] acolls = agroup.getAttributeCollections();
for (int k = 0; k < acolls.length; k++){
AttributeCollection acoll = acolls[k];
acoll.setTemplateDrivenFlag(1);
List ads = acoll.getAttributeDescriptions();
for (int l = 0; l < ads.size(); l++){
AttributeDescription ad = (AttributeDescription) ads.get(l);
if (!ad.getInternalName().matches("\\w+\\.\\w+")
&& !ad.getInternalName().matches("\\w+\\.\\w+\\.\\w+"))
ad.setTemplateDrivenFlag(1);
}
ads = acoll.getAttributeLists();
for (int l = 0; l < ads.size(); l++){
AttributeList ad = (AttributeList) ads.get(l);
if (!ad.getInternalName().matches("\\w+\\.\\w+")
&& !ad.getInternalName().matches("\\w+\\.\\w+\\.\\w+"))
ad.setTemplateDrivenFlag(1);
}
}
}
}
}
//Set the window's location.
setLocation(xOffset * openFrameCount, yOffset * openFrameCount);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Test purposes only. Creates a frame with a JTree containing
* a presepecified DatasetConfig.dtd compatible configuration file.
* @param args
* @throws ConfigurationException
*/
public static void main(String[] args) throws ConfigurationException {
}
/**
* @return
*/
public DatasetConfig getDatasetConfig() {
return datasetConfig;
}
public MartEditor getEditor() {
return editor;
}
public void addAttributesTable(JTable table) {
add(this.getContentPane(), new JScrollPane(table), constraints, 1, 0, 1, 1);
}
public void add(Container cont, Component component, GridBagConstraints constraints, int x, int y, int w, int h) {
constraints.gridx = x;
constraints.gridy = y;
constraints.gridwidth = w;
constraints.gridheight = h;
cont.add(component, constraints);
}
/**
* @param tree
*/
public void setNaiveTree(DatasetConfigTree tree) {
naiveTree = tree;
}
/**
* @param config
*/
public void setDatasetConfig(DatasetConfig config) {
clearDatasetConfig();
datasetConfig = config;
loadDatasetConfig();
}
/**
* Loads the datasetConfig by creating a tree to represent it
* and displaying it.
*/
private void loadDatasetConfig() {
}
/**
* Removes current dataset config if one is loaded, otherwise does nothing.
*/
private void clearDatasetConfig() {
}
public void save(){
tree.save();
}
public void save_as(){
tree.save_as();
}
public void export() throws ConfigurationException{
tree.export();
}
public void exportTemplate() throws ConfigurationException{
if (naiveTree!=null) {
if (!naiveTree.export()) return;
naiveTree = null;
}
tree.exportTemplate();
}
public void validateTemplate() throws ConfigurationException{
tree.validateTemplate();
}
public void cut(){
tree.cut();
}
public void copy(){
tree.copy();
}
public void paste(){
tree.paste();
}
public void makeHidden(){
tree.makeHidden();
}
public void insert(){
// tree.insert();
}
public void delete(){
tree.delete();
}
public void setFileChooserPath(File file){
this.file = file;
editor.setFileChooserPath(file);
}
public File getFileChooserPath(){
return editor.getFileChooserPath();
}
/** Returns an ImageIcon, or null if the path was invalid. */
protected static ImageIcon createImageIcon(String path) {
java.net.URL imgURL = DatasetConfigTreeWidget.class.getClassLoader().getResource(path);
if (imgURL != null) {
return new ImageIcon(imgURL);
} else {
System.err.println("Couldn't find file: " + path);
return null;
}
}
}
class CloseListener implements InternalFrameListener {
public void internalFrameClosed(InternalFrameEvent e) {
}
public void internalFrameOpened(InternalFrameEvent e) {
}
public void internalFrameIconified(InternalFrameEvent e) {
}
public void internalFrameDeiconified(InternalFrameEvent e) {
}
public void internalFrameActivated(InternalFrameEvent e) {
}
public void internalFrameDeactivated(InternalFrameEvent e) {
}
public void internalFrameClosing(InternalFrameEvent e){
try{
DatasetConfigTreeWidget dw = (DatasetConfigTreeWidget) e.getInternalFrame();
if (!MartEditor.getDatabaseDatasetConfigUtils().isDatasetConfigChanged(null,dw.getDatasetConfig())){// current and db out of synch
int returnType = JOptionPane.showConfirmDialog(null,"Close?","Changes not exported",JOptionPane.OK_CANCEL_OPTION);
if (returnType == 0){
e.getInternalFrame().dispose();
}
}
else{
e.getInternalFrame().dispose();
}
}
catch(Exception exc){
// connection changed already
e.getInternalFrame().dispose();
}
}
}
class MyRenderer extends DefaultTreeCellRenderer {
public MyRenderer() {
}
public Component getTreeCellRendererComponent(
JTree tree,
Object value,
boolean sel,
boolean expanded,
boolean leaf,
int row,
boolean hasFocus) {
if (isHidden(value)){
setTextNonSelectionColor(Color.lightGray);
setTextSelectionColor(Color.lightGray);
} else{
setTextNonSelectionColor(Color.black);
setTextSelectionColor(Color.black);
}
super.getTreeCellRendererComponent(
tree, value, sel,
expanded, leaf, row,
hasFocus);
return this;
}
protected boolean isHidden(Object value) {
DatasetConfigTreeNode node =
(DatasetConfigTreeNode)value;
BaseConfigurationObject nodeObject = (BaseConfigurationObject) node.getUserObject();
if (nodeObject.getAttribute("hidden") != null && nodeObject.getAttribute("hidden").equals("true")){
return true;
}
return false;
}
}