/*
* Copyright 2003-2010 Tufts University Licensed under the
* Educational Community 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://www.osedu.org/licenses/ECL-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License 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 tufts.vue;
import tufts.vue.BrowseDataSource.ConfigField;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
import static edu.tufts.vue.ui.ConfigurationUI.*;
public class EditLibraryPanel extends JPanel implements ActionListener
{
private static final org.apache.log4j.Logger Log = org.apache.log4j.Logger.getLogger(EditLibraryPanel.class);
private final JButton updateButton = new JButton(VueResources.getString("optiondialog.savechages.save"));
private final edu.tufts.vue.dsm.DataSource dataSource;
private final tufts.vue.DataSource oldStyleDataSource;
private final ContentViewer dsv;
private edu.tufts.vue.ui.ConfigurationUI cui;
// edu.tufts.vue.ui.ConfigurationUI uses XML to set up its fields. This is probably
// overkill and is adding lots of extra complexity -- e.g., to make it easy to
// add a single new field to a data-source, we've had to create a whole bunch
// of helper code on top of it (see BrowseDataSource)
public EditLibraryPanel(ContentViewer dsv, edu.tufts.vue.dsm.DataSource dataSource)
{
this.dsv = dsv;
this.dataSource = dataSource;
this.oldStyleDataSource = null;
try {
final String xml = dataSource.getConfigurationUIHints();
if (DEBUG.DR) Log.debug("OSID-XML: " + xml);
cui = new edu.tufts.vue.ui.ConfigurationUI(new java.io.ByteArrayInputStream(xml.getBytes("UTF-8")));
cui.setProperties(dataSource.getConfiguration());
updateButton.addActionListener(this);
layoutConfig();
} catch (Throwable t) {
Log.error("init", t);
}
}
private static class UIParams {
String xml;
// possible enumerated types, indexed by key field
Map<String,Vector> extraValuesByKey = Collections.EMPTY_MAP;
}
public EditLibraryPanel(ContentViewer dsv, tufts.vue.DataSource dataSource)
{
this.dsv = dsv;
this.dataSource = null;
this.oldStyleDataSource = dataSource;
try {
//final String xml = getXMLforOldStyleDataSource(dataSource);
final UIParams uiParams = getXMLforOldStyleDataSource(dataSource);
final String xml = uiParams.xml;
if (DEBUG.DR) Log.debug("VUE-XML: " + xml);
cui = new edu.tufts.vue.ui.ConfigurationUI(new java.io.ByteArrayInputStream(xml.getBytes("UTF-8")),
uiParams.extraValuesByKey);
updateButton.addActionListener(this);
layoutConfig();
} catch (Throwable t) {
Log.error("init", t);
}
}
private UIParams getXMLforOldStyleDataSource(tufts.vue.DataSource dataSource)
{
final UIParams params = new UIParams();
final StringBuilder b = new StringBuilder();
final String name = dataSource.getDisplayName();
//final String address = dataSource.getAddress();
b.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
b.append("<configuration>\n");
addField(b, "name", VueResources.getString("dialog.displayname.label"), "Name for this data source", name, SINGLE_LINE_CLEAR_TEXT_CONTROL, 0);
if (dataSource instanceof LocalFileDataSource) {
// use canned configuration
addField(b, "address",
VueResources.getString("dialog.startingpath.label"),
"The path to start from",
dataSource.getAddress(),
FILECHOOSER_CONTROL,
0);
} else if (dataSource instanceof FavoritesDataSource) {
// nothing to add: just uses the name
} else if (dataSource instanceof RemoteFileDataSource) {
// use canned configuration
final RemoteFileDataSource ds = (RemoteFileDataSource) dataSource;
addField(b, "address", "Address", "FTP Address", ds.getAddress(), SINGLE_LINE_CLEAR_TEXT_CONTROL, 0);
addField(b, "username", "Username", "FTP site username", ds.getUserName(), SINGLE_LINE_CLEAR_TEXT_CONTROL, 16);
addField(b, "pasword", "Password", "FTP site password", ds.getPassword(), SINGLE_LINE_MASKED_TEXT_CONTROL, 16);
} else if (dataSource instanceof tufts.vue.BrowseDataSource) {
final tufts.vue.BrowseDataSource ds = (tufts.vue.BrowseDataSource) dataSource;
final java.util.Map<String,Vector> extraValuesMap = new java.util.HashMap();
for (ConfigField f : ds.getConfigurationUIFields()) {
addField(b, f.key, f.title, f.description, f.value, f.uiControl, f.maxLen);
if (f.values != null)
extraValuesMap.put(f.key, f.values);
}
params.extraValuesByKey = extraValuesMap;
}
b.append("</configuration>");
params.xml = b.toString();
//return b.toString();
return params;
}
public static void addField(StringBuilder b, String key, String title, String description, String value, int uiControl, int max)
{
b.append("<field>");
b.append("<key>" + key + "</key>");
b.append("<title>" + title + "</title>");
b.append("<description>" + description + "</description>");
b.append("<default>");
if (value != null)
b.append(org.apache.commons.lang.StringEscapeUtils.escapeXml(value));
b.append("</default>");
b.append("<mandatory>true</mandatory>"); // currently required as input, but ignored for effect by ConfigurationUI impl
b.append("<maxChars>");
b.append(max);
b.append("</maxChars>");
b.append("<ui>" + uiControl + "</ui>");
b.append("</field>\n");
}
private void layoutConfig()
{
if (DEBUG.BOXES) {
cui.setBorder(BorderFactory.createLineBorder(Color.green));
this.setBorder(BorderFactory.createLineBorder(Color.red));
}
final GridBagConstraints gbc = new GridBagConstraints();
final GridBagLayout gridbag = new GridBagLayout();
setLayout(gridbag);
// Set up common GBC config:
gbc.insets = (Insets) tufts.vue.gui.GUI.WidgetInsets.clone();
gbc.insets.bottom = 0;
gbc.weightx = 1;
gbc.weighty = 0;
//-------------------------------------------------------
// Add ConfigurationUI
//-------------------------------------------------------
gbc.anchor = GridBagConstraints.NORTH;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.gridy = 0;
add(cui, gbc);
//-------------------------------------------------------
// Add Save button
//-------------------------------------------------------
gbc.gridwidth = 1;
gbc.gridy = 1;
gbc.ipadx = 15; // this actually makes the button wider
gbc.anchor = GridBagConstraints.NORTHEAST;
gbc.fill = GridBagConstraints.NONE;
add(updateButton, gbc);
//-------------------------------------------------------
// Add a default vertical expander so above content
// will float to top.
//-------------------------------------------------------
gbc.ipadx = 0;
gbc.gridy = 2;
gbc.weighty = 1; // this is the key for the expander to work (non-zero y-weight)
gbc.fill = GridBagConstraints.BOTH;
gbc.gridheight = GridBagConstraints.REMAINDER;
gbc.gridwidth = 0;
final JComponent fill;
if (DEBUG.BOXES) {
fill = new JLabel(VueResources.getString("jlabel.fill"), JLabel.CENTER);
fill.setBackground(Color.gray);
fill.setOpaque(true);
} else {
fill = new JPanel();
}
add(fill, gbc);
}
public void actionPerformed(ActionEvent ae)
{
try {
if (ae.getSource() instanceof JButton) {
if (this.dataSource != null) {
this.dataSource.setConfiguration(cui.getProperties());
this.dsv.setActiveDataSource(this.dataSource); // refresh
edu.tufts.vue.dsm.DataSourceManager dsm = edu.tufts.vue.dsm.impl.VueDataSourceManager.getInstance();
dsm.save();
} else if (this.oldStyleDataSource != null) {
this.oldStyleDataSource.setConfiguration(cui.getProperties());
this.dsv.setActiveDataSource(this.oldStyleDataSource); // refresh
}
}
DataSourceViewer.saveDataSourceViewer();
} catch (Throwable t) {
t.printStackTrace();
VueUtil.alert(VueResources.getString("dialog.config.message")+ t.getMessage(),VueResources.getString("dialog.config.title"));
}
}
}