/* * Copyright (C) 2009 Google Inc. * * Licensed under the Apache 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.apache.org/licenses/LICENSE-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 com.google.sites.liberation.util; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.Arrays; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.border.EmptyBorder; import com.google.api.client.auth.oauth2.Credential; import com.google.api.client.auth.oauth2.TokenResponseException; import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeRequestUrl; import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeTokenRequest; import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse; import com.google.api.client.http.HttpTransport; import com.google.api.client.http.javanet.NetHttpTransport; import com.google.api.client.json.jackson2.JacksonFactory; import com.google.gdata.client.sites.SitesService; import com.google.inject.Guice; import com.google.inject.Injector; import com.google.sites.liberation.export.SiteExporter; import com.google.sites.liberation.export.SiteExporterModule; import com.google.sites.liberation.imprt.SiteImporter; import com.google.sites.liberation.imprt.SiteImporterModule; /** * Provides a GUI for initiating a Sites import or export. * * @author [email protected] (Benjamin Simon) */ public class GuiMain { private static final Logger LOGGER = Logger.getLogger(GuiMain.class .getCanonicalName()); private List<String> SCOPES = Arrays .asList("https://sites.google.com/feeds"); private String CLIENT_ID = "457238310484-d7jjdra9vvij0ubk3k7vr59n8cb7eceh.apps.googleusercontent.com"; private String REDIRECT_URI = "urn:ietf:wg:oauth:2.0:oob"; private Credential credential = null; private JFrame optionsFrame; private JFrame progressFrame; private JTextField hostField; private JTextField domainField; private JTextField webspaceField; private JTextField tokenField; private JTextField fileField; private JFileChooser fileChooser; private JCheckBox revisionsCheckBox; private JTextArea textArea; private JProgressBar progressBar; private JButton doneButton; private GuiMain() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException e) { LOGGER.log(Level.WARNING, "Unable to set look and feel.", e); } catch (InstantiationException e) { LOGGER.log(Level.WARNING, "Unable to set look and feel.", e); } catch (IllegalAccessException e) { LOGGER.log(Level.WARNING, "Unable to set look and feel.", e); } catch (UnsupportedLookAndFeelException e) { LOGGER.log(Level.WARNING, "Unable to set look and feel.", e); } initOptionsFrame(); initProgressFrame(); } private void initOptionsFrame() { optionsFrame = new JFrame("Sites Import/Export"); JPanel mainPanel = new JPanel(); GridLayout layout = new GridLayout(0, 2); mainPanel.setLayout(layout); mainPanel.add(new JLabel(" Host: ")); hostField = new JTextField("sites.google.com"); mainPanel.add(hostField); mainPanel.add(new JLabel(" Domain: ")); domainField = new JTextField(); mainPanel.add(domainField); mainPanel.add(new JLabel(" Webspace: ")); webspaceField = new JTextField(); mainPanel.add(webspaceField); mainPanel.add(new JLabel(" Import/Export Revisions: ")); revisionsCheckBox = new JCheckBox(); mainPanel.add(revisionsCheckBox); fileField = new JTextField(); fileField.setEditable(false); fileChooser = new JFileChooser(); JButton directoryButton = new JButton("Choose Target Directory"); fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); directoryButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { int result = fileChooser.showOpenDialog(optionsFrame); if (result == JFileChooser.APPROVE_OPTION) { fileField.setText(fileChooser.getSelectedFile().getPath()); } } }); mainPanel.add(directoryButton); mainPanel.add(fileField); JButton openBrowserButton = new JButton("Get a token from browser"); openBrowserButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { openBrowserAndGetToken(); } }); mainPanel.add(openBrowserButton); tokenField = new JTextField(); mainPanel.add(tokenField); mainPanel.add(new JPanel()); mainPanel.add(new JPanel()); JButton importButton = new JButton("Import to Sites"); importButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (checkArguments()) { startAction(false); } } }); mainPanel.add(importButton); JButton exportButton = new JButton("Export from Sites"); exportButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (checkArguments()) { startAction(true); } } }); mainPanel.add(exportButton); mainPanel.setBorder(new EmptyBorder(10, 10, 10, 10)); optionsFrame.getContentPane().add(mainPanel); optionsFrame.pack(); optionsFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); optionsFrame.setVisible(true); } private void initProgressFrame() { progressFrame = new JFrame("Progress"); JPanel mainPanel = new JPanel(); mainPanel.setLayout(new BorderLayout()); progressBar = new JProgressBar(); progressBar.setMinimum(0); progressBar.setMaximum(100); progressBar.setPreferredSize(new Dimension(500, 25)); JPanel progressPanel = new JPanel(); progressPanel.add(progressBar); progressPanel.setBorder(new EmptyBorder(10, 0, 0, 0)); mainPanel.add(progressPanel, BorderLayout.NORTH); textArea = new JTextArea(); textArea.setRows(20); textArea.setEditable(false); JScrollPane scrollPane = new JScrollPane(textArea); scrollPane.setBorder(new EmptyBorder(10, 10, 10, 10)); mainPanel.add(scrollPane, BorderLayout.CENTER); doneButton = new JButton("Done"); doneButton.setPreferredSize(new Dimension(495, 25)); doneButton.setEnabled(false); doneButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { doneButton.setEnabled(false); progressFrame.setVisible(false); optionsFrame.setVisible(true); } }); JPanel donePanel = new JPanel(); donePanel.setLayout(new BorderLayout()); donePanel.add(doneButton, BorderLayout.CENTER); donePanel.setBorder(new EmptyBorder(0, 10, 10, 10)); mainPanel.add(donePanel, BorderLayout.SOUTH); progressFrame.getContentPane().add(mainPanel); progressFrame.pack(); progressFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } private void openBrowserAndGetToken() { // Step 1: Authorize --> String authorizationUrl = new GoogleAuthorizationCodeRequestUrl( CLIENT_ID, REDIRECT_URI, SCOPES).build(); try { // Point or redirect your user to the authorizationUrl. java.awt.Desktop.getDesktop().browse(new URI(authorizationUrl)); } catch (Exception e) { LOGGER.warning("Unable to open browser: " + e.toString()); LOGGER.info("Go to: " + authorizationUrl); JOptionPane.showMessageDialog(optionsFrame, "Cannot open browser. Check the console for the necessary URL.", "Error", JOptionPane.ERROR_MESSAGE); } // End of Step 1 <-- } /** * Retrieve OAuth 2.0 credentials. * * @return OAuth 2.0 Credential instance. * @throws IOException */ private Credential getCredentials() throws IOException { String code = tokenField.getText(); HttpTransport transport = new NetHttpTransport(); JacksonFactory jsonFactory = new JacksonFactory(); String CLIENT_SECRET = "EPME5fbwiNLCcMsnj3jVoXeY"; // Step 2: Exchange --> GoogleTokenResponse response = new GoogleAuthorizationCodeTokenRequest( transport, jsonFactory, CLIENT_ID, CLIENT_SECRET, code, REDIRECT_URI).execute(); // End of Step 2 <-- // Build a new GoogleCredential instance and return it. return new GoogleCredential.Builder() .setClientSecrets(CLIENT_ID, CLIENT_SECRET) .setJsonFactory(jsonFactory).setTransport(transport).build() .setAccessToken(response.getAccessToken()) .setRefreshToken(response.getRefreshToken()); } private void startAction(boolean export) { optionsFrame.setVisible(false); progressBar.setValue(0); progressBar.setIndeterminate(true); textArea.setText(""); progressFrame.setVisible(true); new Thread(new ImportExportRunnable(export)).start(); } private boolean checkArguments() { if (hostField.getText().equals("")) { error("Please provide a host name."); return false; } if (webspaceField.getText().equals("")) { error("Please provide a webspace (site name)."); return false; } if (tokenField.getText().equals("")) { error("Please provide a token."); return false; } if (fileChooser.getSelectedFile() == null) { error("Please provide a target directory."); return false; } try { if (credential == null) credential = getCredentials(); } catch (TokenResponseException e) { error("The token is invalid!"); return false; } catch (IOException e) { error(e.toString()); return false; } return true; } private void error(String message) { JOptionPane.showMessageDialog(optionsFrame, message, "Error", JOptionPane.ERROR_MESSAGE); } /** * Launches a new GuiMain, allowing a user to graphically initiate a Sites * import or export. */ public static void main(String[] args) { new GuiMain(); } private class ImportExportRunnable implements Runnable { private boolean export; ImportExportRunnable(boolean export) { this.export = export; } @Override public void run() { String host = hostField.getText(); String domain = (domainField.getText().equals("")) ? null : domainField.getText(); String webspace = webspaceField.getText(); boolean revisions = revisionsCheckBox.isSelected(); File directory = fileChooser.getSelectedFile(); String applicationName = "sites-liberation-5"; SitesService sitesService = new SitesService(applicationName); sitesService.setOAuth2Credentials(credential); if (export) { Injector injector = Guice.createInjector(new SiteExporterModule()); SiteExporter siteExporter = injector.getInstance(SiteExporter.class); siteExporter.exportSite(host, domain, webspace, revisions, sitesService, directory, new GuiProgressListener(progressBar, textArea)); } else { Injector injector = Guice.createInjector(new SiteImporterModule()); SiteImporter siteImporter = injector.getInstance(SiteImporter.class); siteImporter.importSite(host, domain, webspace, revisions, sitesService, directory, new GuiProgressListener(progressBar, textArea)); } doneButton.setEnabled(true); } } }