From 0e44acbb2fec928a1606dc60f427a148fff405c9 Mon Sep 17 00:00:00 2001
From: Mohamed Ragab <moragab@gmail.com>
Date: Wed, 02 May 2012 11:15:01 -0400
Subject: [PATCH] Added a script to facilitate setting the proxy host and port and no proxy hosts, and then it concatenates all the java system properties for setting the java proxy configurations and puts the resulting string in an environment variable JAVA_PROXY_CONFIG, modified the scirpts gitblit,  gitblit-ubuntu, and gitblit-centos to source the java-proxy-config.sh script and then include the resulting java proxy configuration in the java command

---
 src/com/gitblit/client/GitblitManager.java |  420 ++++++++++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 340 insertions(+), 80 deletions(-)

diff --git a/src/com/gitblit/client/GitblitManager.java b/src/com/gitblit/client/GitblitManager.java
index f777fdb..dd0315f 100644
--- a/src/com/gitblit/client/GitblitManager.java
+++ b/src/com/gitblit/client/GitblitManager.java
@@ -16,74 +16,150 @@
 package com.gitblit.client;
 
 import java.awt.BorderLayout;
+import java.awt.Cursor;
 import java.awt.Dimension;
 import java.awt.EventQueue;
-import java.awt.Font;
-import java.awt.GridLayout;
+import java.awt.Point;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.KeyEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
 import java.io.IOException;
+import java.net.ConnectException;
+import java.text.MessageFormat;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.TimeZone;
 
 import javax.swing.ImageIcon;
 import javax.swing.JFrame;
-import javax.swing.JLabel;
 import javax.swing.JMenu;
 import javax.swing.JMenuBar;
 import javax.swing.JMenuItem;
 import javax.swing.JOptionPane;
 import javax.swing.JPanel;
-import javax.swing.JPasswordField;
 import javax.swing.JTabbedPane;
-import javax.swing.JTextField;
 import javax.swing.KeyStroke;
+import javax.swing.SwingWorker;
 import javax.swing.UIManager;
 
+import org.eclipse.jgit.errors.ConfigInvalidException;
+import org.eclipse.jgit.lib.StoredConfig;
+import org.eclipse.jgit.storage.file.FileBasedConfig;
+import org.eclipse.jgit.util.FS;
+
 import com.gitblit.Constants;
+import com.gitblit.GitBlitException.ForbiddenException;
+import com.gitblit.models.FeedModel;
+import com.gitblit.utils.Base64;
 import com.gitblit.utils.StringUtils;
 
 /**
- * Sample RPC application.
+ * Gitblit Manager issues JSON RPC requests to a Gitblit server.
  * 
  * @author James Moger
  * 
  */
-public class GitblitManager extends JFrame {
+public class GitblitManager extends JFrame implements RegistrationsDialog.RegistrationListener {
 
 	private static final long serialVersionUID = 1L;
+	private static final String SERVER = "server";
+	private static final String FEED = "feed";
+	private final SimpleDateFormat dateFormat;
 	private JTabbedPane serverTabs;
-	private GitblitRegistration localhost = new GitblitRegistration("default",
-			"https://localhost:8443", "admin", "admin".toCharArray());
+	private File configFile = new File(System.getProperty("user.home"), ".gitblit/config");
 
-	private List<GitblitRegistration> registrations = new ArrayList<GitblitRegistration>();
+	private Map<String, GitblitRegistration> registrations = new LinkedHashMap<String, GitblitRegistration>();
 	private JMenu recentMenu;
+	private int maxRecentCount = 5;
 
 	private GitblitManager() {
 		super();
+		dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
+		dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
 	}
 
 	private void initialize() {
 		setContentPane(getCenterPanel());
 		setIconImage(new ImageIcon(getClass().getResource("/gitblt-favicon.png")).getImage());
-
 		setTitle("Gitblit Manager v" + Constants.VERSION + " (" + Constants.VERSION_DATE + ")");
 		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-		setSize(800, 500);
+		addWindowListener(new WindowAdapter() {
+			@Override
+			public void windowClosing(WindowEvent event) {
+				saveSizeAndPosition();
+			}
+
+			@Override
+			public void windowOpened(WindowEvent event) {
+				manageRegistrations();
+			}
+		});
+
+		setSizeAndPosition();
+		loadRegistrations();
+		rebuildRecentMenu();
 	}
 
-	public void setVisible(boolean value) {
-		if (value) {
-			if (registrations.size() == 0) {
-				// default prompt
-				loginPrompt(localhost);
-			} else if (registrations.size() == 1) {
-				// single registration prompt
-				loginPrompt(registrations.get(0));
-			}
-			super.setVisible(value);
+	private void setSizeAndPosition() {
+		String sz = null;
+		String pos = null;
+		try {
+			StoredConfig config = getConfig();
+			sz = config.getString("ui", null, "size");
+			pos = config.getString("ui", null, "position");
+		} catch (Throwable t) {
+			t.printStackTrace();
+		}
+
+		// try to restore saved window size
+		if (StringUtils.isEmpty(sz)) {
+			setSize(850, 500);
+		} else {
+			String[] chunks = sz.split("x");
+			int width = Integer.parseInt(chunks[0]);
+			int height = Integer.parseInt(chunks[1]);
+			setSize(width, height);
+		}
+
+		// try to restore saved window position
+		if (StringUtils.isEmpty(pos)) {
 			setLocationRelativeTo(null);
+		} else {
+			String[] chunks = pos.split(",");
+			int x = Integer.parseInt(chunks[0]);
+			int y = Integer.parseInt(chunks[1]);
+			setLocation(x, y);
+		}
+	}
+
+	private void saveSizeAndPosition() {
+		try {
+			// save window size and position
+			StoredConfig config = getConfig();
+			Dimension sz = GitblitManager.this.getSize();
+			config.setString("ui", null, "size",
+					MessageFormat.format("{0,number,0}x{1,number,0}", sz.width, sz.height));
+			Point pos = GitblitManager.this.getLocationOnScreen();
+			config.setString("ui", null, "position",
+					MessageFormat.format("{0,number,0},{1,number,0}", pos.x, pos.y));
+			config.save();
+		} catch (Throwable t) {
+			Utils.showException(GitblitManager.this, t);
 		}
 	}
 
@@ -93,25 +169,17 @@
 		menuBar.add(serversMenu);
 		recentMenu = new JMenu(Translation.get("gb.recent"));
 		serversMenu.add(recentMenu);
-		JMenuItem login = new JMenuItem(Translation.get("gb.login") + "...");
-		login.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_L, KeyEvent.CTRL_DOWN_MASK, false));
-		login.addActionListener(new ActionListener() {
+
+		JMenuItem manage = new JMenuItem(Translation.get("gb.manage") + "...");
+		manage.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_M, KeyEvent.CTRL_DOWN_MASK, false));
+		manage.addActionListener(new ActionListener() {
 			public void actionPerformed(ActionEvent event) {
-				loginPrompt(localhost);
+				manageRegistrations();
 			}
 		});
-		serversMenu.add(login);
-		return menuBar;
-	}
+		serversMenu.add(manage);
 
-	private JPanel newLabelPanel(String text, JTextField field) {
-		JLabel label = new JLabel(text);
-		label.setFont(label.getFont().deriveFont(Font.BOLD));
-		label.setPreferredSize(new Dimension(75, 10));
-		JPanel jpanel = new JPanel(new BorderLayout());
-		jpanel.add(label, BorderLayout.WEST);
-		jpanel.add(field, BorderLayout.CENTER);
-		return jpanel;
+		return menuBar;
 	}
 
 	private JPanel getCenterPanel() {
@@ -123,56 +191,101 @@
 		return panel;
 	}
 
-	private boolean loginPrompt(GitblitRegistration reg) {
-		JTextField urlField = new JTextField(reg.url, 30);
-		JTextField nameField = new JTextField(reg.name);
-		JTextField accountField = new JTextField(reg.account);
-		JPasswordField passwordField = new JPasswordField(new String(reg.password));
-
-		JPanel panel = new JPanel(new GridLayout(0, 1, 5, 5));
-		panel.add(newLabelPanel(Translation.get("gb.name"), nameField));
-		panel.add(newLabelPanel(Translation.get("gb.url"), urlField));
-		panel.add(newLabelPanel(Translation.get("gb.username"), accountField));
-		panel.add(newLabelPanel(Translation.get("gb.password"), passwordField));
-
-		int result = JOptionPane.showConfirmDialog(GitblitManager.this, panel,
-				Translation.get("gb.login"), JOptionPane.OK_CANCEL_OPTION);
-		if (result != JOptionPane.OK_OPTION) {
-			return false;
-		}
-		String url = urlField.getText();
-		if (StringUtils.isEmpty(url)) {
-			return false;
-		}
-		reg = new GitblitRegistration(nameField.getText(), url, accountField.getText(),
-				passwordField.getPassword());
-		boolean success = login(reg);
-		registrations.add(0, reg);
-		rebuildRecentMenu();
-		return success;
+	private void manageRegistrations() {
+		RegistrationsDialog dialog = new RegistrationsDialog(new ArrayList<GitblitRegistration>(
+				registrations.values()), this);
+		dialog.setLocationRelativeTo(GitblitManager.this);
+		dialog.setVisible(true);
 	}
 
-	private boolean login(GitblitRegistration reg) {
-		try {
-			GitblitPanel panel = new GitblitPanel(reg);
-			panel.login();
-			serverTabs.addTab(reg.name, panel);
-			int idx = serverTabs.getTabCount() - 1;
-			serverTabs.setSelectedIndex(idx);
-			serverTabs.setTabComponentAt(idx, new ClosableTabComponent(reg.name, null, serverTabs,
-					panel));
-			return true;
-		} catch (IOException e) {
-			JOptionPane.showMessageDialog(GitblitManager.this, e.getMessage(),
-					Translation.get("gb.error"), JOptionPane.ERROR_MESSAGE);
+	@Override
+	public void login(GitblitRegistration reg) {
+		if (!reg.savePassword && (reg.password == null || reg.password.length == 0)) {
+			// prompt for password
+			EditRegistrationDialog dialog = new EditRegistrationDialog(this, reg, true);
+			dialog.setLocationRelativeTo(GitblitManager.this);
+			dialog.setVisible(true);
+			GitblitRegistration newReg = dialog.getRegistration();
+			if (newReg == null) {
+				// user canceled
+				return;
+			}
+			// preserve feeds
+			newReg.feeds.addAll(reg.feeds);
+
+			// use new reg
+			reg = newReg;
 		}
-		return false;
+
+		// login
+		setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+		final GitblitRegistration registration = reg;
+		final GitblitPanel panel = new GitblitPanel(registration, this);
+		SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() {
+
+			@Override
+			protected Boolean doInBackground() throws IOException {
+				panel.login();
+				return true;
+			}
+
+			@Override
+			protected void done() {
+				try {
+					boolean success = get();
+					serverTabs.addTab(registration.name, panel);
+					int idx = serverTabs.getTabCount() - 1;
+					serverTabs.setSelectedIndex(idx);
+					serverTabs.setTabComponentAt(idx, new ClosableTabComponent(registration.name,
+							null, serverTabs, panel));
+					registration.lastLogin = new Date();
+					saveRegistration(registration.name, registration);
+					registrations.put(registration.name, registration);
+					rebuildRecentMenu();
+					if (!registration.savePassword) {
+						// clear password
+						registration.password = null;
+					}
+				} catch (Throwable t) {
+					Throwable cause = t.getCause();
+					if (cause instanceof ConnectException) {
+						JOptionPane.showMessageDialog(GitblitManager.this, cause.getMessage(),
+								Translation.get("gb.error"), JOptionPane.ERROR_MESSAGE);
+					} else if (cause instanceof ForbiddenException) {
+						JOptionPane
+								.showMessageDialog(
+										GitblitManager.this,
+										"This Gitblit server does not allow RPC Management or Administration",
+										Translation.get("gb.error"), JOptionPane.ERROR_MESSAGE);
+					} else {
+						Utils.showException(GitblitManager.this, t);
+					}
+				} finally {
+					setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+				}
+			}
+		};
+		worker.execute();
 	}
 
 	private void rebuildRecentMenu() {
 		recentMenu.removeAll();
-		for (final GitblitRegistration reg : registrations) {
-			JMenuItem item = new JMenuItem(reg.name);
+		ImageIcon icon = new ImageIcon(getClass().getResource("/gitblt-favicon.png"));
+		List<GitblitRegistration> list = new ArrayList<GitblitRegistration>(registrations.values());
+		Collections.sort(list, new Comparator<GitblitRegistration>() {
+			@Override
+			public int compare(GitblitRegistration o1, GitblitRegistration o2) {
+				return o2.lastLogin.compareTo(o1.lastLogin);
+			}
+		});
+		if (list.size() > maxRecentCount) {
+			list = list.subList(0, maxRecentCount);
+		}
+		for (int i = 0; i < list.size(); i++) {
+			final GitblitRegistration reg = list.get(i);
+			JMenuItem item = new JMenuItem(reg.name, icon);
+			item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_1 + i, KeyEvent.CTRL_DOWN_MASK,
+					false));
 			item.addActionListener(new ActionListener() {
 				public void actionPerformed(ActionEvent e) {
 					login(reg);
@@ -182,6 +295,153 @@
 		}
 	}
 
+	private void loadRegistrations() {
+		try {
+			StoredConfig config = getConfig();
+			Set<String> servers = config.getSubsections(SERVER);
+			for (String server : servers) {
+				Date lastLogin = new Date(0);
+				String date = config.getString(SERVER, server, "lastLogin");
+				if (!StringUtils.isEmpty(date)) {
+					lastLogin = dateFormat.parse(date);
+				}
+				String url = config.getString(SERVER, server, "url");
+				String account = config.getString(SERVER, server, "account");
+				char[] password;
+				String pw = config.getString(SERVER, server, "password");
+				if (StringUtils.isEmpty(pw)) {
+					password = new char[0];
+				} else {
+					password = new String(Base64.decode(pw)).toCharArray();
+				}
+				GitblitRegistration reg = new GitblitRegistration(server, url, account, password) {
+					private static final long serialVersionUID = 1L;
+
+					protected void cacheFeeds() {
+						writeFeedCache(this);
+					}
+				};
+				String[] feeds = config.getStringList(SERVER, server, FEED);
+				if (feeds != null) {
+					// deserialize the field definitions
+					for (String definition : feeds) {
+						FeedModel feed = new FeedModel(definition);
+						reg.feeds.add(feed);
+					}
+				}
+				reg.lastLogin = lastLogin;
+				loadFeedCache(reg);
+				registrations.put(reg.name, reg);
+			}
+		} catch (Throwable t) {
+			Utils.showException(GitblitManager.this, t);
+		}
+	}
+
+	@Override
+	public boolean saveRegistration(String name, GitblitRegistration reg) {
+		try {
+			StoredConfig config = getConfig();
+			if (!StringUtils.isEmpty(name) && !name.equals(reg.name)) {
+				// delete old registration
+				registrations.remove(name);
+				config.unsetSection(SERVER, name);
+			}
+
+			// update registration
+			config.setString(SERVER, reg.name, "url", reg.url);
+			config.setString(SERVER, reg.name, "account", reg.account);
+			if (reg.savePassword) {
+				config.setString(SERVER, reg.name, "password",
+						Base64.encodeBytes(new String(reg.password).getBytes("UTF-8")));
+			} else {
+				config.setString(SERVER, reg.name, "password", "");
+			}
+			if (reg.lastLogin != null) {
+				config.setString(SERVER, reg.name, "lastLogin", dateFormat.format(reg.lastLogin));
+			}
+			// serialize the feed definitions
+			List<String> definitions = new ArrayList<String>();
+			for (FeedModel feed : reg.feeds) {
+				definitions.add(feed.toString());
+			}
+			if (definitions.size() > 0) {
+				config.setStringList(SERVER, reg.name, FEED, definitions);
+			}
+			config.save();
+			return true;
+		} catch (Throwable t) {
+			Utils.showException(GitblitManager.this, t);
+		}
+		return false;
+	}
+
+	@Override
+	public boolean deleteRegistrations(List<GitblitRegistration> list) {
+		boolean success = false;
+		try {
+			StoredConfig config = getConfig();
+			for (GitblitRegistration reg : list) {
+				config.unsetSection(SERVER, reg.name);
+				registrations.remove(reg.name);
+			}
+			config.save();
+			success = true;
+		} catch (Throwable t) {
+			Utils.showException(GitblitManager.this, t);
+		}
+		return success;
+	}
+
+	private StoredConfig getConfig() throws IOException, ConfigInvalidException {
+		FileBasedConfig config = new FileBasedConfig(configFile, FS.detect());
+		config.load();
+		return config;
+	}
+
+	private void loadFeedCache(GitblitRegistration reg) {
+		File feedCache = new File(configFile.getParentFile(), StringUtils.getSHA1(reg.toString())
+				+ ".cache");
+		if (!feedCache.exists()) {
+			// no cache for this registration
+			return;
+		}
+		try {
+			BufferedReader reader = new BufferedReader(new FileReader(feedCache));
+			Map<String, Date> cache = new HashMap<String, Date>();
+			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
+			String line = null;
+			while ((line = reader.readLine()) != null) {
+				String[] kvp = line.split("=");
+				cache.put(kvp[0], df.parse(kvp[1]));
+			}
+			reader.close();
+			for (FeedModel feed : reg.feeds) {
+				String name = feed.toString();
+				if (cache.containsKey(name)) {
+					feed.currentRefreshDate = cache.get(name);
+				}
+			}
+		} catch (Exception e) {
+			Utils.showException(GitblitManager.this, e);
+		}
+	}
+
+	private void writeFeedCache(GitblitRegistration reg) {
+		try {
+			File feedCache = new File(configFile.getParentFile(), StringUtils.getSHA1(reg
+					.toString()) + ".cache");
+			FileWriter writer = new FileWriter(feedCache);
+			for (FeedModel feed : reg.feeds) {
+				writer.append(MessageFormat.format("{0}={1,date,yyyy-MM-dd'T'HH:mm:ss}\n",
+						feed.toString(), feed.currentRefreshDate));
+			}
+			writer.close();
+		} catch (Exception e) {
+			Utils.showException(GitblitManager.this, e);
+		}
+	}
+
 	public static void main(String[] args) {
 		EventQueue.invokeLater(new Runnable() {
 			public void run() {

--
Gitblit v1.9.1