0001: package tide.export;
0002:
0003: import java.text.DateFormat;
0004: import java.text.SimpleDateFormat;
0005: import tide.editor.Accelerators;
0006: import java.awt.Color;
0007: import tide.editor.MainEditorFrame;
0008: import snow.utils.*;
0009: import javax.swing.border.EmptyBorder;
0010: import tide.project.ProjectSettings;
0011: import java.net.*;
0012: import java.util.concurrent.*;
0013: import java.awt.Insets;
0014: import java.awt.FlowLayout;
0015: import snow.utils.storage.FileUtils;
0016: import java.awt.EventQueue;
0017: import java.util.*;
0018: import snow.sortabletable.*;
0019: import java.io.File;
0020: import snow.utils.gui.*;
0021: import javax.swing.*;
0022: import javax.swing.event.*;
0023: import java.awt.BorderLayout;
0024: import java.awt.event.*;
0025:
0026: /** Allow choosing which files to export (autoselects files aged less than 1 hour)
0027: * TODO: compare with existing url (http, ftp, ...) // just compare actual local files dates, ignore files only on server...
0028: *<p>
0029: * [Feb2008]: added correct ftp login, and auto mode
0030: */
0031: public final class ExportDialog extends JDialog {
0032: private final FilesModel filesModel;
0033: private final SortableTableModel stm;
0034: private final JTable table;
0035:
0036: private final JTextField compareURL = new JTextField(25);
0037: private final JComboBox publishType = new JComboBox(new String[] {
0038: "ftp", "file" });
0039: private final JTextField publishFTPDestField = new JTextField(19);
0040: private final JTextField ftpUser = new JTextField(4);
0041: private final JPasswordField ftpPass = new JPasswordField(4);
0042: private final FileField publishFolderDestination = new FileField(
0043: "", true, "Choose the publish folder destination",
0044: JFileChooser.DIRECTORIES_ONLY);
0045:
0046: private final FileField folderToExport;
0047:
0048: // showed only when publishing to FTP destination
0049: private final JPanel ftpPublishPanel = new JPanel(new FlowLayout(
0050: FlowLayout.LEFT, 0, 0));
0051: // showed only when publishing to folder
0052: private final JPanel dirPublishPanel = new JPanel(new FlowLayout(
0053: FlowLayout.LEFT, 0, 0));
0054:
0055: final private JCheckBox includeSubFiles = new JCheckBox(
0056: "Include subfolders in the view", true);
0057: final private JCheckBox closeTIDEAtEnd = new JCheckBox(
0058: "Close tIDE after successful export", false);
0059: final private JCheckBox autoStartPublish = new JCheckBox(
0060: "Automatically start publishing next time", false);
0061: final private JCheckBox closeDialogAtEnd = new JCheckBox(
0062: "Close this dialog after export", true);
0063:
0064: // Currently realy sets the date of the source file (and of course the destination, then).
0065: final private JCheckBox setCopiedDate = new JCheckBox(
0066: "Set exported files dates to", false);
0067: final private DateFormat dateFormat = new SimpleDateFormat(
0068: "dd.MM.yyyy HH:mm");
0069: final private JTextField dateField = new JTextField(dateFormat
0070: .format(System.currentTimeMillis()), 10);
0071:
0072: public final List<String> defaultFTPS = Arrays
0073: .asList("ftp://upload.sourceforge.net/incoming::anonymous::anonymous");
0074:
0075: private void saveSettings(ProjectSettings settings) {
0076: //""+folderToExport.getPath() // only read,set in the project props
0077: settings.setProperty("JAR_FTP_DEST_HOST", publishFTPDestField
0078: .getText());
0079: settings.setProperty("JAR_FTP_USER", ftpUser.getText());
0080: settings.setProperty("JAR_FTP_PASS", new String(ftpPass
0081: .getPassword()));
0082: settings.setProperty("JAR_PUBLISH_TYPE", ""
0083: + publishType.getSelectedItem());
0084: settings.setProperty("JAR_DIR_DEST_HOST", ""
0085: + publishFolderDestination.getPath());
0086:
0087: settings.setBooleanProperty("Export_auto", autoStartPublish
0088: .isSelected());
0089: settings.setBooleanProperty("Export_closeTIDEAtEnd",
0090: closeTIDEAtEnd.isSelected());
0091: settings.setBooleanProperty("Export_closeDialogAtEnd",
0092: closeDialogAtEnd.isSelected());
0093: settings.setBooleanProperty("Export_includeSubFiles",
0094: includeSubFiles.isSelected());
0095:
0096: // project specific
0097: publishFolderDestination.rememberPathForGlobalCompletion(
0098: settings.getProps(), "exportDestinations");
0099:
0100: // store
0101: if (publishType.getSelectedItem().equals("ftp")) {
0102: List<String> dests = settings.getProps().getArrayProperty(
0103: "export_ftps", defaultFTPS);
0104: String dest = publishFTPDestField.getText() + "::"
0105: + ftpUser.getText().trim();
0106: if (!dests.contains(dest) && !dest.equals("::")
0107: && !defaultFTPS.contains(dest)) {
0108: dests.add(dest);
0109: settings.getProps().setArrayProperty("export_ftps",
0110: dests);
0111: }
0112: }
0113: }
0114:
0115: public ExportDialog(final JFrame parent,
0116: final ProjectSettings settings, final boolean standalone) {
0117: super (parent, "Exporting project", true); // MODAL
0118:
0119: //only read
0120: final File jarFile = new File(settings.getProperty(
0121: "JAR_DESTINATION", ""));
0122: final File exportSourceFolder = jarFile.getParentFile();
0123:
0124: publishFTPDestField.setText(settings.getProperty(
0125: "JAR_FTP_DEST_HOST", ""));
0126: ftpUser.setText(settings.getProperty("JAR_FTP_USER", ""));
0127: ftpPass.setText(settings.getProperty("JAR_FTP_PASS", ""));
0128: publishType.setSelectedItem(settings.getProperty(
0129: "JAR_PUBLISH_TYPE", "file"));
0130: publishFolderDestination.setPath(settings.getProperty(
0131: "JAR_DIR_DEST_HOST", ""));
0132: autoStartPublish.setSelected(settings.getBooleanProperty(
0133: "Export_auto", false));
0134: closeTIDEAtEnd.setSelected(settings.getBooleanProperty(
0135: "Export_closeTIDEAtEnd", false));
0136: closeDialogAtEnd.setSelected(settings.getBooleanProperty(
0137: "Export_closeDialogAtEnd", true));
0138: includeSubFiles.setSelected(settings.getBooleanProperty(
0139: "Export_includeSubFiles", false));
0140:
0141: publishFolderDestination.offerRememberedGlobalCompletion(
0142: settings.getProps(), "exportDestinations");
0143:
0144: // north
0145: JPanel northPanel = new JPanel();
0146: northPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
0147: GridLayout3 glNorth = new GridLayout3(2, northPanel);
0148:
0149: add(northPanel, BorderLayout.NORTH);
0150: //glNorth.addTitleSeparator("Folder to export");
0151: folderToExport = new FileField(exportSourceFolder, false,
0152: "Choose the folder to export",
0153: JFileChooser.DIRECTORIES_ONLY);
0154: glNorth.add("Folder to export");
0155: glNorth.add(folderToExport);
0156: folderToExport.setComponentWidth(360);
0157: folderToExport.setAutoColorized();
0158:
0159: glNorth.add("");
0160: glNorth.add(includeSubFiles);
0161:
0162: folderToExport.addActionListener(new ActionListener() {
0163: public void actionPerformed(ActionEvent ae) {
0164: filesModel.setRoot(folderToExport.getPath());
0165: }
0166: });
0167:
0168: glNorth.addTitleSeparator("Destination");
0169: glNorth.add(publishType);
0170:
0171: final JPanel publishDestPanel = new JPanel(new FlowLayout(
0172: FlowLayout.LEFT, 0, 0));
0173:
0174: glNorth.add(publishDestPanel);
0175:
0176: publishType.addActionListener(new ActionListener() {
0177: public void actionPerformed(ActionEvent ae) {
0178: ftpPublishPanel.setVisible(publishType
0179: .getSelectedIndex() == 0);
0180: dirPublishPanel.setVisible(publishType
0181: .getSelectedIndex() == 1);
0182: }
0183: });
0184: ftpPublishPanel.setVisible(publishType.getSelectedIndex() == 0);
0185: dirPublishPanel.setVisible(publishType.getSelectedIndex() == 1);
0186:
0187: publishDestPanel.add(ftpPublishPanel);
0188: publishDestPanel.add(dirPublishPanel);
0189:
0190: dirPublishPanel.add(publishFolderDestination);
0191: publishFolderDestination.setComponentWidth(360);
0192:
0193: ftpPublishPanel.add(publishFTPDestField);
0194:
0195: final JButton ftpLocs = new JButton(Icons.sharedDownWedge);
0196: ftpPublishPanel.add(ftpLocs);
0197: ftpLocs.setMargin(new Insets(0, 0, 0, 0));
0198: ftpLocs.setFocusPainted(false);
0199: ftpLocs.addActionListener(new ActionListener() {
0200: public void actionPerformed(ActionEvent ae) {
0201: List<String> dests = settings.getProps()
0202: .getArrayProperty("export_ftps", defaultFTPS);
0203: if (dests.isEmpty())
0204: return;
0205: JPopupMenu pop = new JPopupMenu();
0206: for (final String di : dests) {
0207: final int pos = di.indexOf("::");
0208: if (pos == 0)
0209: continue;
0210: final String url = di.substring(0, pos);
0211:
0212: JMenuItem mi = new JMenuItem(di);
0213: pop.add(mi);
0214: mi.addActionListener(new ActionListener() {
0215: public void actionPerformed(ActionEvent ae2) {
0216: String usr = di.substring(pos + 2);
0217: int pos2 = usr.indexOf("::");
0218: String pass = "";
0219: if (pos2 > 0) {
0220: pass = usr.substring(pos2 + 2);
0221: usr = usr.substring(0, pos2);
0222: }
0223: ftpUser.setText(usr);
0224: ftpPass.setText(pass);
0225:
0226: publishFTPDestField.setText(url);
0227: }
0228: });
0229: }
0230: pop.show(publishFTPDestField, 0, ftpLocs.getHeight());
0231:
0232: }
0233: });
0234:
0235: ftpPublishPanel.add(new JLabel(" user: "));
0236: ftpPublishPanel.add(ftpUser);
0237:
0238: ftpPublishPanel.add(new JLabel(" pass: "));
0239: ftpPublishPanel.add(ftpPass);
0240:
0241: includeSubFiles.addActionListener(new ActionListener() {
0242: public void actionPerformed(ActionEvent ae) {
0243: filesModel.addRemoveSubFiles(includeSubFiles
0244: .isSelected());
0245: }
0246: });
0247: /*
0248: JButton comp = new JButton("Compare");
0249: comp.setMargin(new Insets(0,2,0,2));
0250: comp.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) {
0251: compareWithURL(compareURL.getText());
0252: } });
0253: glNorth.add(comp);
0254: glNorth.add(compareURL);
0255: */
0256:
0257: // maybe useful to keep open if exporting to several places
0258: if (!standalone) {
0259: glNorth.addTitleSeparator("Options");
0260: glNorth.add("");
0261: glNorth.add(closeTIDEAtEnd);
0262: closeTIDEAtEnd
0263: .setToolTipText("Especially useful if you have also checked the option 'shutdown computer on tIDE close'");
0264:
0265: glNorth.add("");
0266: glNorth.add(autoStartPublish);
0267:
0268: glNorth.add("");
0269: glNorth.add(closeDialogAtEnd);
0270: }
0271:
0272: if (MainEditorFrame.enableExperimental) {
0273: glNorth.add("");
0274: JPanel fdp = new JPanel(new FlowLayout(FlowLayout.LEFT, 2,
0275: 0));
0276: glNorth.add(fdp);
0277: fdp.add(setCopiedDate);
0278: fdp.add(dateField);
0279: setCopiedDate.addActionListener(new ActionListener() {
0280: public void actionPerformed(ActionEvent ae) {
0281: dateField.setEditable(setCopiedDate.isSelected());
0282: }
0283: });
0284: dateField.setEditable(setCopiedDate.isSelected());
0285:
0286: }
0287:
0288: glNorth.addTitleSeparator("Selected files to export");
0289:
0290: // center
0291: filesModel = new FilesModel(exportSourceFolder);
0292: stm = new SortableTableModel(filesModel, 2, true);
0293: table = new JTable(stm);
0294: stm.installGUI(table);
0295: JPanel tablePanel = new JPanel(new BorderLayout(0, 0));
0296: add(tablePanel, BorderLayout.CENTER);
0297: tablePanel.add(new JScrollPane(table), BorderLayout.CENTER);
0298: AdvancedSearchPanel asp = new AdvancedSearchPanel("Filter: ",
0299: null, stm, false);
0300: tablePanel.add(asp, BorderLayout.NORTH);
0301:
0302: JPanel southControlPanel = new JPanel(new FlowLayout(
0303: FlowLayout.RIGHT, 5, 2));
0304: add(southControlPanel, BorderLayout.SOUTH);
0305:
0306: JButton cancel = new JButton("Cancel", Icons.sharedCross);
0307: southControlPanel.add(cancel);
0308: cancel.setMargin(new Insets(0, 2, 0, 2));
0309: cancel.addActionListener(new ActionListener() {
0310: public void actionPerformed(ActionEvent ae) {
0311: // cancel
0312: setVisible(false);
0313: }
0314: });
0315:
0316: JButton export = new JButton("Export marked files",
0317: Icons.sharedRightArrow);
0318: southControlPanel.add(export);
0319: export.setMargin(new Insets(0, 2, 0, 2));
0320: export.setBackground(Color.orange);
0321:
0322: ActionListener expaction = new ActionListener() {
0323: public void actionPerformed(ActionEvent ae) {
0324: saveSettings(settings);
0325:
0326: final ProgressModalDialog pmd = new ProgressModalDialog(
0327: ExportDialog.this , "Publishing ", true);
0328: pmd.start();
0329: Thread t = new Thread() {
0330: public void run() {
0331: try {
0332: doExport(pmd, exportSourceFolder,
0333: getMarkedFiles(), closeDialogAtEnd
0334: .isSelected());
0335: } catch (Exception e) {
0336: JOptionPane.showMessageDialog(
0337: ExportDialog.this , "Error: "
0338: + e.getMessage(),
0339: "Publication failed",
0340: JOptionPane.WARNING_MESSAGE);
0341: e.printStackTrace();
0342: } finally {
0343: pmd.closeDialog();
0344: }
0345: }
0346: };
0347: t.start();
0348: }
0349: };
0350:
0351: export.addActionListener(expaction);
0352:
0353: if (autoStartPublish.isSelected()) {
0354: expaction.actionPerformed(null);
0355: }
0356:
0357: table.addMouseListener(new MouseAdapter() {
0358: @Override
0359: public void mousePressed(MouseEvent me) {
0360: if (me.isPopupTrigger()) {
0361: showPopup(me);
0362: }
0363: }
0364:
0365: @Override
0366: public void mouseReleased(MouseEvent me) {
0367: if (me.isPopupTrigger()) {
0368: showPopup(me);
0369: }
0370: }
0371:
0372: public void showPopup(MouseEvent me) {
0373: JPopupMenu popup = new JPopupMenu();
0374: final List<FileItem> sf = new ArrayList<FileItem>();
0375: int[] sel = table.getSelectedRows();
0376: for (int sr : sel) {
0377: int ind = stm.getIndexInUnsortedFromTablePos(sr);
0378: sf.add(filesModel.getFileItemAt(ind));
0379: }
0380:
0381: final List<FileItem> visible = new ArrayList<FileItem>();
0382: for (int i = 0; i < table.getRowCount(); i++) {
0383: int ind = stm.getIndexInUnsortedFromTablePos(i);
0384: visible.add(filesModel.getFileItemAt(ind));
0385: }
0386:
0387: if (sf.size() > 0) {
0388: JMenuItem ms = new JMenuItem("Select to export");
0389: ms.addActionListener(new ActionListener() {
0390: public void actionPerformed(ActionEvent ae) {
0391: filesModel.setMarked(true, sf);
0392: }
0393: });
0394: popup.add(ms);
0395:
0396: JMenuItem msu = new JMenuItem("Unselect to export");
0397: msu.addActionListener(new ActionListener() {
0398: public void actionPerformed(ActionEvent ae) {
0399: filesModel.setMarked(false, sf);
0400: }
0401: });
0402: popup.add(msu);
0403:
0404: popup.addSeparator();
0405: }
0406:
0407: JMenuItem msa = new JMenuItem("Select all");
0408: msa.addActionListener(new ActionListener() {
0409: public void actionPerformed(ActionEvent ae) {
0410: filesModel.setMarked(true, visible);
0411: }
0412: });
0413: popup.add(msa);
0414:
0415: JMenuItem msua = new JMenuItem("Unselect all");
0416: msua.addActionListener(new ActionListener() {
0417: public void actionPerformed(ActionEvent ae) {
0418: filesModel.setMarkedForAll(false); // also the not visibles
0419: }
0420: });
0421: popup.add(msua);
0422:
0423: popup.show(table, me.getX(), me.getY());
0424: }
0425:
0426: });
0427:
0428: ((JComponent) getContentPane()).registerKeyboardAction(
0429: new ActionListener() {
0430: public void actionPerformed(ActionEvent ae) {
0431: setVisible(false);
0432: }
0433: }, "Escape", Accelerators.escape,
0434: JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
0435:
0436: setSize(550, 650);
0437: this .setLocationRelativeTo(parent);
0438: setVisible(true); //MODAL!!
0439:
0440: }
0441:
0442: // TODO
0443: void compareWithURL(String url) {
0444: url = url.replace("\\", "/");
0445: if (!url.endsWith("/"))
0446: url += "/";
0447: final String urls = url;
0448: ExecutorService executor = Executors.newFixedThreadPool(5);
0449: filesModel.setIsCompared();
0450: stm.setAllColumnsVisible();
0451: stm.setPreferredColumnSizesFromModel();
0452:
0453: for (final FileItem fi : filesModel.fileItems) {
0454: fi.comparaisonStatus = "looking";
0455: filesModel.update();
0456:
0457: executor.submit(new Runnable() {
0458: public void run() {
0459: try {
0460: fi.comparaisonStatus = "opening connection";
0461: filesModel.update();
0462: URL hurl = new URL(urls + fi.relName);
0463: HttpURLConnection hurlc = (HttpURLConnection) hurl
0464: .openConnection();
0465: fi.dateOfComparedFile = hurlc.getLastModified();
0466:
0467: //System.out.println(""+hurlc.getHeaderFields());
0468: if (hurlc.toString().endsWith("404.html")) {
0469: fi.comparaisonStatus = "NOT FOUND";
0470: } else {
0471:
0472: // resp code is always 200 !
0473: long dd = fi.dateOfComparedFile
0474: - fi.f.lastModified();
0475: long ds = hurlc.getContentLength()
0476: - fi.f.length();
0477: if (Math.abs(dd) < 10000) {
0478: fi.comparaisonStatus = "same";
0479: } else if (dd > 0) {
0480: fi.comparaisonStatus = "newer "
0481: + DateUtils
0482: .formatTimeDifference(dd);
0483: } else {
0484: fi.comparaisonStatus = "older "
0485: + DateUtils
0486: .formatTimeDifference(dd);
0487: }
0488:
0489: if (ds != 0) {
0490: fi.comparaisonStatus += ", " + ds
0491: + " bytes";
0492: }
0493: }
0494: filesModel.update();
0495: hurlc.disconnect();
0496: } catch (Exception e) {
0497: e.printStackTrace();
0498: fi.comparaisonStatus = "" + e.getMessage();
0499: }
0500: }
0501: });
0502: }
0503:
0504: //TODO
0505: }
0506:
0507: private void doExport(ProgressModalDialog pmd, File parentFolder,
0508: List<FileItem> files, boolean closeDialogAtEnd)
0509: throws Exception {
0510: long totSizeToSend = 0;
0511: for (FileItem f : files) {
0512: totSizeToSend += f.f.length();
0513: }
0514: pmd.setProgressValue(0, "");
0515: pmd.setProgressBounds(1000);
0516: int remainingProgress = pmd.getMaxValue();
0517:
0518: System.out.println("Exporting "
0519: + FileUtils.formatSize(totSizeToSend));
0520: pmd.setProgressSection("Exporting " + files.size() + " file"
0521: + (files.size() == 1 ? "" : "s") + ", "
0522: + FileUtils.formatSize(totSizeToSend)); // auto:...
0523:
0524: int srcRootLength = FileUtils.getCanonicalName(
0525: parentFolder.getParentFile()).length();
0526: long startTime = System.currentTimeMillis();
0527:
0528: boolean errors = false;
0529:
0530: long dateToSet = -1; // -1 => do not set
0531: if (MainEditorFrame.enableExperimental
0532: && setCopiedDate.isSelected()) {
0533: try { // try a raw long !
0534: dateToSet = Long.parseLong(dateField.getText());
0535: } catch (Exception ignored) {
0536: // try a date.
0537: try {
0538: dateToSet = dateFormat.parse(dateField.getText())
0539: .getTime();
0540: } catch (Exception e) {
0541: e.printStackTrace();
0542: }
0543: }
0544: }
0545:
0546: if (publishType.getSelectedItem().equals("ftp")) {
0547: String pass = new String(this .ftpPass.getPassword());
0548: final String dest = publishFTPDestField.getText();
0549: final String user = this .ftpUser.getText();
0550:
0551: if (dest.trim().length() == 0)
0552: throw new Exception(
0553: "Please provide a non empty FTP destination");
0554:
0555: if (pass.length() == 0) {
0556: pass = JOptionPane.showInputDialog(null,
0557: "Enter the password to publish on " + "\n "
0558: + dest + "\nwith username=" + user);
0559: if (pass == null)
0560: return;
0561: }
0562:
0563: long alreadySend = 0;
0564:
0565: writeOutLine("\nPublishing " + files.size() + " files ("
0566: + FileUtils.formatSize(totSizeToSend) + ") on "
0567: + dest + ", user=" + this .ftpUser.getText());
0568:
0569: int n = 0;
0570: for (FileItem f : files) {
0571: if (dateToSet > 0) {
0572: f.f.setLastModified(dateToSet);
0573: }
0574:
0575: n++;
0576: long fileStartTime = System.currentTimeMillis();
0577:
0578: String relName = f.relName;
0579: try {
0580: String destName = dest;
0581: if (!destName.endsWith("/"))
0582: destName += "/";
0583: destName += relName;
0584:
0585: pmd.setProgressComment(relName);
0586: writeOut(" " + relName);
0587:
0588: MainEditorFrame.debugOut("FTP " + f.f + " => "
0589: + destName);
0590: //System.out.println("FTP "+f.f+" => "+destName+", user="+user+", pass="+pass);
0591:
0592: NetUtils.publishFTP(f.f, destName, user, pass, pmd,
0593: alreadySend, totSizeToSend);
0594:
0595: f.comparaisonStatus = "uploaded";
0596: filesModel.update();
0597: writeOutLine(" (transferred at "
0598: + NetUtils.formatNetSpeed(f.f.length(),
0599: System.currentTimeMillis()
0600: - fileStartTime) + ")");
0601:
0602: alreadySend += f.f.length();
0603: } catch (Exception e) {
0604: e.printStackTrace();
0605:
0606: writeOutErrorLine(" (failed)");
0607: errors = true;
0608:
0609: f.comparaisonStatus = "" + e.getMessage();
0610:
0611: if (n == files.size()) // don't ask to publish the next !
0612: {
0613: throw new Exception("FTP upload failed for "
0614: + relName + " :\n " + e.getMessage());
0615: }
0616:
0617: int rep = JOptionPane
0618: .showConfirmDialog(
0619: this ,
0620: "Error: "
0621: + e.getMessage()
0622: + "\ncontinue with the other files ?",
0623: "Publication failed",
0624: JOptionPane.YES_NO_CANCEL_OPTION,
0625: JOptionPane.WARNING_MESSAGE);
0626: if (rep != JOptionPane.YES_OPTION) {
0627: writeOutErrorLine("Publication cancelled");
0628: throw new Exception("FTP upload cancelled");
0629: }
0630:
0631: }
0632: }
0633: } else if (publishType.getSelectedItem().equals("file")) {
0634: // normal file transfer
0635: // verify that the jar dest and publish dest are distinct
0636: File pd = parentFolder;
0637: File destFolderBase = this .publishFolderDestination
0638: .getPath();
0639: pmd.setProgressBounds(files.size());
0640:
0641: if (destFolderBase == null)
0642: throw new Exception(
0643: "Please provide a non empty destination folder");
0644:
0645: if (pd.equals(destFolderBase)) {
0646: errors = true;
0647: throw new RuntimeException(
0648: "Cannot publish: the jar destination and the publication paths are identical.");
0649: }
0650:
0651: String destName = destFolderBase.getAbsolutePath();
0652: if (!destName.endsWith("/"))
0653: destName += "/";
0654:
0655: File destFold = new File(destName);
0656:
0657: if (!destFold.exists()) {
0658: destFold.mkdirs();
0659: }
0660:
0661: if (!destFold.isDirectory()) {
0662: errors = true;
0663: throw new Exception(
0664: "The publication destination must be a directory:\n "
0665: + destFold);
0666: }
0667:
0668: writeOutLine("\nPublishing " + files.size() + " files ("
0669: + FileUtils.formatSize(totSizeToSend) + ") on "
0670: + destFold + ":");
0671:
0672: try {
0673: for (FileItem f : files) {
0674: if (dateToSet > 0) {
0675: f.f.setLastModified(dateToSet);
0676: }
0677:
0678: long fileStartTime = System.currentTimeMillis();
0679:
0680: f.comparaisonStatus = "uploading...";
0681: String relName = f.relName;
0682:
0683: String destf = destName + relName;
0684: pmd.setProgressComment("" + relName);
0685: pmd.incrementProgress(1);
0686: writeOut(" " + relName);
0687:
0688: FileUtils.copy(f.f, new File(destf));
0689: f.comparaisonStatus = "uploaded";
0690: filesModel.update();
0691:
0692: writeOutLine(" (transferred at "
0693: + NetUtils.formatNetSpeed(f.f.length(),
0694: System.currentTimeMillis()
0695: - fileStartTime) + ")");
0696:
0697: }
0698: } catch (Exception e) {
0699: errors = true;
0700: throw e;
0701: }
0702:
0703: } else // not file nor ftp mode ?
0704: {
0705: // unknown export...
0706: errors = true;
0707: throw new Exception();
0708: }
0709: filesModel.update();
0710:
0711: if (closeDialogAtEnd)
0712: setVisible(false);
0713:
0714: writeOutLine("Export done in "
0715: + DateUtils.formatTimeDifference(System
0716: .currentTimeMillis()
0717: - startTime) + ".\n");
0718: if (MainEditorFrame.instance != null) {
0719: MainEditorFrame.instance.outputPanels.tideOutputPanel
0720: .setCaretEnd();
0721: }
0722:
0723: System.out.println("Export terminated, at "
0724: + NetUtils.formatNetSpeed(totSizeToSend, System
0725: .currentTimeMillis()
0726: - startTime));
0727:
0728: if (this .closeTIDEAtEnd.isSelected() && !errors) {
0729: // Especially useful if the option "shutdown at tide termination" in the debug menu is selected.
0730: // "click export and go on holliday".
0731: MainEditorFrame.instance.terminateTIDE();
0732: }
0733: }
0734:
0735: private void writeOutLine(String txt) {
0736: writeOut(txt + "\r\n");
0737: }
0738:
0739: private void writeOut(String txt) {
0740: if (MainEditorFrame.instance != null) {
0741: MainEditorFrame.instance.outputPanels.tideOutputPanel.doc
0742: .append(txt);
0743: } else {
0744: System.out.print(txt);
0745: }
0746: }
0747:
0748: private void writeOutErrorLine(String txt) {
0749: writeOutError(txt + "\r\n");
0750: }
0751:
0752: private void writeOutError(String txt) {
0753: if (MainEditorFrame.instance != null) {
0754: MainEditorFrame.instance.outputPanels.tideOutputPanel.doc
0755: .appendError(txt);
0756: } else {
0757: System.err.print(txt);
0758: }
0759: }
0760:
0761: private List<FileItem> getMarkedFiles() {
0762: List<FileItem> fm = filesModel.getMarkedFiles();
0763: List<FileItem> ret = new ArrayList<FileItem>();
0764: for (FileItem fi : fm) {
0765: ret.add(fi);
0766: }
0767: return ret;
0768: }
0769:
0770: static class FilesModel extends FineGrainTableModel {
0771: final List<FileItem> fileItems = new Vector<FileItem>();
0772: private final List<FileItem> subFilesTemporaryHidden = new Vector<FileItem>();
0773:
0774: public FilesModel(File root) {
0775: setRoot(root);
0776: }
0777:
0778: public void setRoot(File root) {
0779: containsSubFiles = false;
0780: fireTableModelWillChange();
0781: fileItems.clear();
0782: subFilesTemporaryHidden.clear();
0783: if (root != null) {
0784: int fl = FileUtils.getCanonicalName(root).length();
0785: addRecurse(root, fl);
0786: }
0787: fireTableDataChanged();
0788: fireTableModelHasChanged();
0789: }
0790:
0791: boolean containsSubFiles = false;
0792:
0793: public void addRemoveSubFiles(boolean add) {
0794: fireTableModelWillChange();
0795: if (add) {
0796: fileItems.addAll(subFilesTemporaryHidden);
0797: subFilesTemporaryHidden.clear();
0798: } else {
0799: for (FileItem fi : fileItems) {
0800: if (fi.isSubFile) {
0801: subFilesTemporaryHidden.add(fi);
0802: }
0803: }
0804: fileItems.removeAll(subFilesTemporaryHidden);
0805: }
0806: fireTableDataChanged();
0807: fireTableModelHasChanged();
0808: }
0809:
0810: private void addRecurse(File root, int fl) {
0811: File[] files = root.listFiles();
0812: if (files != null) {
0813:
0814: for (File fi : files) {
0815: if (fi.isFile()) {
0816: fileItems.add(new FileItem(fi, fl));
0817: } else {
0818: // recurse
0819: addRecurse(fi, fl);
0820: containsSubFiles = true;
0821: }
0822: }
0823: }
0824: }
0825:
0826: public FileItem getFileItemAt(int row) {
0827: return fileItems.get(row);
0828: }
0829:
0830: public List<FileItem> getMarkedFiles() {
0831: List<FileItem> mf = new ArrayList<FileItem>();
0832: for (FileItem fi : fileItems) {
0833: if (fi.export)
0834: mf.add(fi);
0835: }
0836: return mf;
0837: }
0838:
0839: @Override
0840: public int getPreferredColumnWidth(int column) {
0841: if (column == 0)
0842: return 3;
0843: if (column == 4)
0844: return 10;
0845: if (column > 2)
0846: return 5;
0847: return 35;
0848: }
0849:
0850: public Object getValueAt(int row, int col) {
0851: FileItem fi = fileItems.get(row);
0852: if (col == 0)
0853: return fi.export;
0854: if (col == 1)
0855: return fi.relName;
0856: if (col == 2)
0857: return DateUtils.formatTimeDifference(System
0858: .currentTimeMillis()
0859: - fi.f.lastModified());
0860: if (col == 3)
0861: return FileUtils.formatSize(fi.f.length());
0862: if (col == 4)
0863: return fi.comparaisonStatus;
0864: return "?";
0865: }
0866:
0867: public int getRowCount() {
0868: return fileItems.size();
0869: }
0870:
0871: boolean compared = false;
0872:
0873: public int getColumnCount() {
0874: return compared ? 5 : 4;
0875: }
0876:
0877: @Override
0878: public boolean isCellEditable(int row, int col) {
0879: return col == 0;
0880: }
0881:
0882: @Override
0883: public void setValueAt(Object v, int row, int col) {
0884:
0885: if (col != 0)
0886: return;
0887:
0888: fireTableModelWillChange();
0889: FileItem fi = fileItems.get(row);
0890: fi.export = Boolean.valueOf("" + v);
0891:
0892: fireTableDataChanged();
0893: fireTableModelHasChanged();
0894: }
0895:
0896: public void update() {
0897: EventQueue.invokeLater(new Runnable() {
0898: public void run() {
0899: fireTableModelWillChange();
0900: fireTableDataChanged();
0901: fireTableModelHasChanged();
0902: }
0903: });
0904: }
0905:
0906: public void setMarkedForAll(boolean export) {
0907: setMarked(export, fileItems);
0908: }
0909:
0910: public void setMarked(boolean export, List<FileItem> fis) {
0911: fireTableModelWillChange();
0912: for (FileItem fi : fis) {
0913: fi.export = export;
0914: }
0915:
0916: fireTableDataChanged();
0917: fireTableModelHasChanged();
0918: }
0919:
0920: public void setIsCompared() {
0921: compared = true;
0922:
0923: this .fireTableStructureChanged();
0924: fireTableModelHasChanged();
0925: }
0926:
0927: @Override
0928: public String getColumnName(int c) {
0929: if (c == 0)
0930: return "Export";
0931: if (c == 1)
0932: return "File";
0933: if (c == 2)
0934: return "Age";
0935: if (c == 3)
0936: return "Size";
0937: return "Comparaison";
0938: }
0939:
0940: @Override
0941: public int compareForColumnSort(int pos1, int pos2, int col) {
0942: if (col == 2) {
0943: long a1 = System.currentTimeMillis()
0944: - fileItems.get(pos1).f.lastModified();
0945: long a2 = System.currentTimeMillis()
0946: - fileItems.get(pos2).f.lastModified();
0947: return Long.valueOf(a1).compareTo(a2);
0948: }
0949:
0950: if (col == 3) {
0951: long s1 = fileItems.get(pos1).f.length();
0952: long s2 = fileItems.get(pos2).f.length();
0953: return Long.valueOf(s1).compareTo(s2);
0954: }
0955: if (col == 4) {
0956: long s1 = fileItems.get(pos1).dateOfComparedFile;
0957: long s2 = fileItems.get(pos2).dateOfComparedFile;
0958: return Long.valueOf(s1).compareTo(s2);
0959: }
0960: return super .compareForColumnSort(pos1, pos2, col);
0961: }
0962: }
0963:
0964: public static class FileItem {
0965: final File f;
0966: String relName;
0967: boolean export = false; // global default !
0968: //boolean selectedInTable = false; // TODO!
0969: boolean isSubFile = false;
0970: long dateOfComparedFile = -1;
0971: String comparaisonStatus = "";
0972:
0973: FileItem(File fi, int baseLength) {
0974: this .f = fi;
0975: relName = f.getAbsolutePath().substring(baseLength)
0976: .replace('\\', '/');
0977: isSubFile = relName.contains("/");
0978:
0979: long age = System.currentTimeMillis() - f.lastModified();
0980: if (age < 1000 * 3600) // 1 hour
0981: {
0982: export = true;
0983: }
0984: }
0985: }
0986:
0987: /*may work standalone*/
0988: public static void main(String[] args) throws Exception {
0989: standalone();
0990: }
0991:
0992: public static void standalone() {
0993: MainEditorFrame.enableExperimental = true;
0994: EventQueue.invokeLater(new Runnable() {
0995: public void run() {
0996: ProjectSettings props = new ProjectSettings();
0997: props
0998: .setProperty("JAR_DESTINATION",
0999: "C:/proj/tide/published/snowmail.sn.funpic.de/tide");
1000: ExportDialog ed = new ExportDialog((JFrame) null,
1001: props, true);
1002: System.exit(0);
1003: }
1004: });
1005: }
1006:
1007: }
|