Topcomponent --sighoff
实现一个置于右边框的Topcomponent:
1、可远程同步更新(根据远程的xml文件),修改(增删)该xml文件,查看、刷新等
2、打包工程,记录该打包后的文件的信息,包括:ProjectName,author,date,message,写入远程xml文件
3、不论是上传该文件信息,还是远程查看该信息,都必须先设置author,repositoryPath,localPath.
4、四个按键:打包文件并写入xml文件信息,远程调用查看该xml文件,刷新查看该xml文件,设置author,repositoryPath,localPath.
代码包括:
class Milestone存储打包文件信息:
class MilestoneTableModel extends AbstractTableModel构造显示的table
interface MilestoneProvider
class Browse extends JPanel 选择文件的按钮和文本显示框
class SystemUtil 包含打包函数(还有一些,没太看)
public final class SignOffTopComponent extends TopComponent implements MilestoneProvider
为主要的Topcomponent代码,包含读、写xml文件
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package com.platformda.signoff; //import com.platformda.system.EditableProject; //import com.platformda.system.EditingProjectService; //import com.platformda.system.SystemUtil; //import com.jtattoo.demo.app.JTattooDemo; import com.jtattoo.plaf.texture.TextureUtils; import com.platformda.utility.common.FileUtil; import com.platformda.utility.ui.SwingUtil; import org.jdom2.Document; import org.jdom2.Element; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.io.File; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.Reader; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.BorderFactory; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.JTextPane; import javax.swing.JToolBar; import javax.swing.ListSelectionModel; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.border.Border; //import javax.swing.text.Element; import org.jdom2.JDOMException; import org.jdom2.input.SAXBuilder; import org.jdom2.output.XMLOutputter; //import javax.xml.bind.Messages; import org.netbeans.api.settings.ConvertAsProperties; import org.netbeans.swing.etable.ETable; import org.openide.DialogDescriptor; import org.openide.DialogDisplayer; import org.openide.NotifyDescriptor; import org.openide.awt.ActionID; import org.openide.awt.ActionReference; import org.openide.util.Exceptions; import org.openide.util.ImageUtilities; import org.openide.util.NbBundle.Messages; import org.openide.util.RequestProcessor; import org.openide.windows.TopComponent; import org.openide.windows.WindowManager; //import sun.misc.RequestProcessor; /** * Top component which displays something. */ @ConvertAsProperties( dtd = "-//com.platformda.signoff//SignOff//EN", autostore = false) @TopComponent.Description( preferredID = "SignOffTopComponent", //iconBase="SET/PATH/TO/ICON/HERE", persistenceType = TopComponent.PERSISTENCE_ALWAYS) @TopComponent.Registration(mode = "rightSlidingSide", openAtStartup = true) @ActionID(category = "Window", id = "com.platformda.signoff.SignOffTopComponent") @ActionReference(path = "Menu/Window" /*, position = 333 */) @TopComponent.OpenActionRegistration( displayName = "#CTL_SignOffAction", preferredID = "SignOffTopComponent") @Messages({ "CTL_SignOffAction=SignOff", "CTL_SignOffTopComponent=Sign Off", "HINT_SignOffTopComponent=Sign Off" }) public final class SignOffTopComponent extends TopComponent implements MilestoneProvider { String author = ""; String repositoryPath = ""; String localPath = ""; private static final RequestProcessor RP = new RequestProcessor(SignOffTopComponent.class); private static final Logger LOG = Logger.getLogger(SignOffTopComponent.class.getName()); public SignOffTopComponent() { initComponents(); customizeComponents(); setName(Bundle.CTL_SignOffTopComponent()); setToolTipText(Bundle.HINT_SignOffTopComponent()); putClientProperty(TopComponent.PROP_KEEP_PREFERRED_SIZE_WHEN_SLIDED_IN, Boolean.TRUE); // com.jtattoo.plaf.texture.TextureLookAndFeel.setTheme("Default", "5u3t-z8qa-91gp-5fxd", "PLATFORM-DA"); // try { // UIManager.setLookAndFeel("com.jtattoo.plaf.texture.TextureLookAndFeel"); // } catch (InstantiationException ex) { // Exceptions.printStackTrace(ex); // } catch (IllegalAccessException ex) { // Exceptions.printStackTrace(ex); // } catch (UnsupportedLookAndFeelException ex) { // Exceptions.printStackTrace(ex); // } catch (ClassNotFoundException ex) { // Exceptions.printStackTrace(ex); // } } /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. */ // <editor-fold defaultstate="collapsed" desc="Generated Code"> private void initComponents() { setLayout(new java.awt.BorderLayout()); }// </editor-fold> // Variables declaration - do not modify // End of variables declaration void updateTable(int selectedIndex) { tableModel.fireTableDataChanged(); if (selectedIndex < 0 || selectedIndex >= milestones.size()) { selectedIndex = 0; } ListSelectionModel tableSelectionModel = table.getSelectionModel(); // set a selection interval (in this case the first row) tableSelectionModel.setSelectionInterval(selectedIndex, selectedIndex); // update the selection model table.setSelectionModel(tableSelectionModel); } Action pushAction = new AbstractAction("Push") { private static final long serialVersionUID = 1L; public void actionPerformed(ActionEvent e) { if (!checkRepository()) { setting(); } if (checkRepository()) { CommitForm form = new CommitForm(); DialogDescriptor desc = new DialogDescriptor(form, "Sign Off", true, DialogDescriptor.OK_CANCEL_OPTION, DialogDescriptor.OK_OPTION, null); desc.setValid(true); Object result = DialogDisplayer.getDefault().notify(desc); // displays the dialog if (result == NotifyDescriptor.OK_OPTION) { refresh(); // final File root = new File(editingProject.getProjectPath()); final File root = new File("D:/ZD/signoff/forzip"); final Milestone ms = new Milestone(); ms.setProjectName(root.getName()); ms.setAuthor(author); ms.setDate(System.currentTimeMillis()); ms.setMessage(form.getMessage()); RP.post(new Runnable() { @Override public void run() { try { final File zip = FileUtil.createTempFile("prj", ".zip", "D:/ZD/signoff"); if (!SystemUtil.buildZip(root, zip)) { if (!zip.delete()) { throw new IOException("Cannot delete " + zip); } return; } File remote = new File(repositoryPath, zip.getName()); FileUtil.copy(zip.getAbsolutePath(), remote.getAbsolutePath()); zip.delete(); ms.setRemotePath(remote.getAbsolutePath()); SwingUtil.invokeLater(new Runnable() { @Override public void run() { milestones.add(ms); updateTable(milestones.size() - 1); try { buildXmlDoc(); } catch (IOException ex) { Exceptions.printStackTrace(ex); } catch (JDOMException ex) { Exceptions.printStackTrace(ex); } } }); } catch (Exception x) { LOG.log(Level.WARNING, null, x); return; } } }); } } } }; Action fetcchAction = new AbstractAction("Fetch") { private static final long serialVersionUID = 1L; public void actionPerformed(ActionEvent e) { if (!checkRepository()) { setting(); } if (checkRepository()) { int selectedindex = table.getSelectedRow(); if (selectedindex > -1) { int index = table.convertRowIndexToModel(selectedindex); Milestone ms = milestones.get(index); File localFile = new File(localPath, ms.getProjectName()); // OpenProjects.getDefault().getOpenProjects(); // EditingProjectService service = EditingProjectService.getInsance(); // EditableProject editingProject = service.getEditingProject(); // if (editingProject != null) { // // String editingPath = PathUtil.getIndependentPath(editingProject.getProjectPath()); // String localPath = PathUtil.getIndependentPath(localFile.getAbsolutePath()); // // if (editingPath.equals(localPath)) { // int answer = JOptionPane.showConfirmDialog(WindowManager.getDefault().getMainWindow(), // "The project to be checked out is already being editing, close and reload?", "Warning", // JOptionPane.YES_NO_OPTION); // if (answer != JOptionPane.YES_OPTION) { // return; // } // // close first // service.unsetEditingProject(editingProject); // } // } File zipFile = new File(ms.getRemotePath()); File root = new File(localPath); try { SystemUtil.unpackAndActivateFirst(zipFile, root); } catch (IOException ex) { Exceptions.printStackTrace(ex); } } } } }; public void buildXmlDoc() throws IOException, JDOMException { Element root = new Element("repository"); int i = 1; for (Milestone milestone : milestones) { Element milestonElement = new Element("milestone"); milestonElement.setAttribute("projectNo", "" + (i++)); milestonElement.addContent(new Element("ProjectName").setText(milestone.getProjectName())); milestonElement.addContent(new Element("Author").setText(milestone.getAuthor())); milestonElement.addContent(new Element("Date").setText(String.valueOf(milestone.getDate()))); milestonElement.addContent(new Element("Message").setText(milestone.getMessage())); root.addContent(milestonElement); } Document Doc = new Document(root); XMLOutputter XMLOut = new XMLOutputter(); // File f = new File(repositoryPath + "/repository.xml"); // if (f.exists()) { // f.delete(); // }else{ // f.createNewFile(); // } XMLOut.output(Doc, new FileOutputStream(repositoryPath + "/repository.xml")); } public static Element getRoot(String path) throws IOException { SAXBuilder saxBuilder = new SAXBuilder(); Reader reader = new FileReader(path); Document document; try { document = saxBuilder.build(reader); } catch (JDOMException e) { throw new IOException(e.getMessage()); } finally { if (reader != null) { reader.close(); } } return (Element) document.getRootElement(); } public boolean checkRepository() { if (author.equals("") || repositoryPath.equals("") || localPath.equals("")) { return false; } return true; } public void refresh() { try { if (!checkRepository()) { setting(); } if (checkRepository()) { milestones.clear(); String path = repositoryPath + "/repository.xml"; File milestonFile = new File(path); if (milestonFile.exists()) { Element rootElement = getRoot(path); Element repositoryElem = rootElement.getChild("repository"); List childrenList = rootElement.getChildren("milestone"); for (int i = 0; i < childrenList.size(); i++) { Element elem = (Element) childrenList.get(i); final Milestone ms = new Milestone(); ms.setProjectName(elem.getChild("ProjectName").getText()); ms.setAuthor(elem.getChild("Author").getText()); ms.setDate(Long.valueOf(elem.getChild("Date").getText())); ms.setMessage(elem.getChild("Message").getText()); milestones.add(ms); updateTable(milestones.size() - 1); } } } } catch (IOException ex) { Exceptions.printStackTrace(ex); } catch (NullPointerException ex) { Exceptions.printStackTrace(ex); } } Action refreshAction = new AbstractAction("Refresh") { private static final long serialVersionUID = 1L; public void actionPerformed(ActionEvent e) { refresh(); } }; public void setting() { JPanel settingPanel = new JPanel(new BorderLayout()); Border border = BorderFactory.createEmptyBorder(10, 10, 10, 10); JPanel westPanel = new JPanel(new GridLayout(0, 1, 5, 5)); JPanel centerPanel = new JPanel(new GridLayout(0, 1, 5, 5)); JLabel authorLabel = new JLabel("author:"); JTextField authorField = new JTextField(author); Browse repositoryPathBrowse = new Browse(); Browse localPathBrowse = new Browse(); repositoryPathBrowse.field.setText(repositoryPath); localPathBrowse.field.setText(localPath); westPanel.removeAll(); westPanel.add(authorLabel); westPanel.add(new JLabel("repositoryPath:")); westPanel.add(new JLabel("localPath:")); centerPanel.removeAll(); authorField.setSize(new Dimension(280, 20)); centerPanel.add(authorField); centerPanel.add(repositoryPathBrowse.getPanel()); centerPanel.add(localPathBrowse.getPanel()); settingPanel.removeAll(); settingPanel.add(westPanel, BorderLayout.WEST); settingPanel.add(centerPanel, BorderLayout.CENTER); settingPanel.setBorder(border); DialogDescriptor settingDescriptor = new DialogDescriptor(settingPanel, "setting", true, DialogDescriptor.OK_CANCEL_OPTION, DialogDescriptor.OK_OPTION, null); Object result = DialogDisplayer.getDefault().notify(settingDescriptor); if (result == NotifyDescriptor.OK_OPTION) { repositoryPath = repositoryPathBrowse.field.getText(); localPath = localPathBrowse.field.getText(); author = authorField.getText(); } } Action settingAction = new AbstractAction("Setting") { private static final long serialVersionUID = 1L; public void actionPerformed(ActionEvent e) { setting(); } }; JToolBar toolBar = new JToolBar(); JButton pushButton = new JButton(); JButton fetchButton = new JButton(); JButton refreshButton = new JButton(); JButton settingButton = new JButton(); final List<Milestone> milestones = new ArrayList<Milestone>(); MilestoneTableModel tableModel; ETable table; private void customizeComponents() { pushButton.setAction(pushAction); pushButton.setIcon(new ImageIcon(ImageUtilities.loadImage( "com/platformda/signoff/resources/push.png"))); pushButton.setText(""); pushAction.putValue(Action.SHORT_DESCRIPTION, "Sign Off"); fetchButton.setAction(fetcchAction); fetchButton.setIcon(new ImageIcon(ImageUtilities.loadImage( "com/platformda/signoff/resources/fetch.png"))); fetchButton.setText(""); fetcchAction .putValue(Action.SHORT_DESCRIPTION, "Check Out"); refreshButton.setAction(refreshAction); refreshButton.setIcon(new ImageIcon(ImageUtilities.loadImage( "com/platformda/signoff/resources/refresh.png"))); refreshButton.setText(""); refreshAction .putValue(Action.SHORT_DESCRIPTION, "Refresh"); settingButton.setAction(settingAction); settingButton.setIcon(new ImageIcon(ImageUtilities.loadImage( "com/platformda/signoff/resources/annotate.png"))); settingButton.setText(""); settingAction .putValue(Action.SHORT_DESCRIPTION, "Options"); toolBar.add(pushButton); // toolBar.addSeparator(); toolBar.add(fetchButton); toolBar.addSeparator(); toolBar.add(refreshButton); toolBar.add(settingButton); toolBar.setFloatable(false); //-----------? // GUIUtil.updateBackground(toolBar); //table tableModel = new MilestoneTableModel((MilestoneProvider) this); table = new ETable(tableModel); //compose add(toolBar, BorderLayout.NORTH); JScrollPane scroll = new JScrollPane(table); scroll.setBorder(null); add(scroll, BorderLayout.CENTER); } @Override public void componentOpened() { // TODO add custom code on component opening } @Override public void componentClosed() { // TODO add custom code on component closing } void writeProperties(java.util.Properties p) { // better to version settings since initial version as advocated at // http://wiki.apidesign.org/wiki/PropertyFiles p.setProperty("version", "1.0"); if (!author.equals("")) { p.setProperty("author", author); } if (!repositoryPath.isEmpty()) { p.setProperty("repositoryPath", repositoryPath); } if (!localPath.isEmpty()) { p.setProperty("localPath", localPath); } } void readProperties(java.util.Properties p) { // String version = p.getProperty("version"); if (p.containsKey("author")) { author = p.getProperty("author"); } if (p.containsKey("repositoryPath")) { repositoryPath = p.getProperty("repositoryPath"); } if (p.containsKey("localPath")) { localPath = p.getProperty("localPath"); } } private static SignOffTopComponent instance; private static final String PREFERRED_ID = "SignOffTopComponent"; /** * Gets default instance. Do not use directly: reserved for .settings files * only, i.e. deserialization routines; otherwise you could get a * non-deserialized instance. To obtain the singleton instance, use * {@link #findInstance}. */ public static synchronized SignOffTopComponent getDefault() { if (instance == null) { instance = new SignOffTopComponent(); } return instance; } /** * Obtain the TaskEditorTopComponent instance. Never call { * @link #getDefault} directly! */ public static synchronized SignOffTopComponent findInstance() { TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID); if (win == null) { Logger.getLogger(SignOffTopComponent.class .getName()). warning("Cannot find " + PREFERRED_ID + " component. It will not be located properly in the window system."); return getDefault(); } if (win instanceof SignOffTopComponent) { return (SignOffTopComponent) win; } Logger.getLogger(SignOffTopComponent.class .getName()). warning("There seem to be multiple components with the '" + PREFERRED_ID + "' ID. That is a potential source of errors and unexpected behavior."); return getDefault(); } @Override public int getMilestoneSize() { return milestones.size(); } @Override public Milestone getMilestone(int index) { return milestones.get(index); } final class CommitForm extends JPanel { JTextPane textPane = new JTextPane(); public CommitForm() { super(new BorderLayout()); textPane.setPreferredSize(new Dimension(400, 300)); add(new JLabel("Message:"), BorderLayout.NORTH); add(textPane, BorderLayout.CENTER); } public String getMessage() { return textPane.getText(); } } }
class Milestone存储打包文件信息:
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package com.platformda.signoff; public class Milestone { String author; long date; String message; String label; String projectName; String remotePath; String localPath; public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public long getDate() { return date; } public void setDate(long date) { this.date = date; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public String getLabel() { return label; } public void setLabel(String label) { this.label = label; } public String getProjectName() { return projectName; } public void setProjectName(String projectName) { this.projectName = projectName; } public String getRemotePath() { return remotePath; } public void setRemotePath(String remotePath) { this.remotePath = remotePath; } public String getLocalPath() { return localPath; } public void setLocalPath(String localPath) { this.localPath = localPath; } }
class MilestoneTableModel extends AbstractTableModel构造显示的table
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package com.platformda.signoff; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import javax.swing.table.AbstractTableModel; public class MilestoneTableModel extends AbstractTableModel { private static final long serialVersionUID = 1L; private MilestoneProvider provider; private String[] columnNames = new String[]{"Project", "Author", "Date", "Message"}; // DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm"); public MilestoneTableModel(MilestoneProvider provider) { this.provider = provider; } @Override public String getColumnName(int columnIndex) { return columnNames[columnIndex]; } // @Override // public Class<?> getColumnClass(int columnIndex) { // return super.getColumnClass(columnIndex); // } @Override public boolean isCellEditable(int rowIndex, int columnIndex) { return false; } @Override public int getColumnCount() { return columnNames.length; } @Override public int getRowCount() { return provider.getMilestoneSize(); } @Override public Object getValueAt(int rowIndex, int columnIndex) { Milestone ms = provider.getMilestone(rowIndex); switch (columnIndex) { case 0: return ms.getProjectName(); case 1: return ms.getAuthor(); case 2: Date date = new Date(); date.setTime(ms.getDate()); // Calendar calendar = Calendar.getInstance(); // calendar.setTimeInMillis(ms.getDate()); return dateFormat.format(date); default: return ms.getMessage(); } } }
interface MilestoneProvider
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package com.platformda.signoff; public interface MilestoneProvider { public int getMilestoneSize(); public Milestone getMilestone(int index); }
class Browse extends JPanel 选择文件的按钮和文本显示框
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package com.platformda.signoff; 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 javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.filechooser.FileFilter; public class Browse extends JPanel { JPanel browseJPanel; String defAnswer; JTextField field; File file; public Browse() { browseJPanel = new JPanel(new BorderLayout()); JPanel editPanel = new JPanel(new GridLayout(1, 1, 5, 5)); JPanel buttonPanel = new JPanel(new GridLayout(1, 1, 5, 5)); field = new JTextField(); field.setPreferredSize(new Dimension(280, 20)); JButton browseButton = new JButton("..."); browseButton.setSize(10, 10); editPanel.add(field); buttonPanel.add(browseButton); browseButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String tFileName = field.getText(); /* * JFileChooser.FILES_AND_DIRECTORIES * JFileChooser.FILES_ONLY */ file = showLoadFileDialog(JFileChooser.FILES_AND_DIRECTORIES, null, tFileName); if (file == null) { return; } field.setText(file.getAbsolutePath()); } }); browseJPanel.add(editPanel, BorderLayout.CENTER); browseJPanel.add(buttonPanel, BorderLayout.EAST); // Border border = BorderFactory.createEmptyBorder(10, 10, 10, 10); // browseJPanel.setBorder(border); } File showLoadFileDialog(int mode, FileFilter filter, String tFileName) { JFileChooser chooser = new JFileChooser(); File tFile = new File(tFileName); if (mode == JFileChooser.FILES_ONLY) { if (!tFile.isFile()) { tFile = new File(""); } } chooser.setSelectedFile(tFile); chooser.setFileSelectionMode(mode); chooser.setMultiSelectionEnabled(false); chooser.resetChoosableFileFilters(); chooser.addChoosableFileFilter(filter); chooser.setFileHidingEnabled(false); int answer = chooser.showOpenDialog(browseJPanel); if (answer != JFileChooser.APPROVE_OPTION) { return null; } return chooser.getSelectedFile(); } public JPanel getPanel() { return browseJPanel; } }
class SystemUtil 包含打包函数(还有一些,没太看)
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package com.platformda.signoff; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import java.util.zip.CRC32; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; import org.netbeans.api.progress.ProgressHandle; import org.netbeans.api.progress.ProgressHandleFactory; import org.netbeans.api.project.Project; import org.netbeans.api.queries.SharabilityQuery; import org.netbeans.api.queries.VisibilityQuery; import org.openide.filesystems.FileUtil; import org.openide.util.Cancellable; import org.openide.util.Utilities; public class SystemUtil { public double value = 1.0; private static SystemUtil instance; private SystemUtil() { } public static SystemUtil getInstance() { if (instance == null) { instance = new SystemUtil(); } return instance; } public static boolean buildZip(File root, File zip) throws IOException { final AtomicBoolean canceled = new AtomicBoolean(); ProgressHandle handle = ProgressHandleFactory.createHandle("Building " + zip.getName(), new Cancellable() { @Override public boolean cancel() { return canceled.compareAndSet(false, true); } }); handle.start(); try { List<String> files = new ArrayList<String>(); scanForFiles(root, files, "", handle, canceled, true); if (canceled.get()) { return false; } handle.switchToDeterminate(files.size()); OutputStream os = new FileOutputStream(zip); try { ZipOutputStream zos = new ZipOutputStream(os); Set<String> written = new HashSet<String>(); String prefix = root.getName() + '/'; for (int i = 0; i < files.size(); i++) { if (canceled.get()) { return false; } String name = files.get(i); writeEntry(prefix + name, written, zos, new File(root, name)); handle.progress("Packed: " + name, i); } zos.finish(); zos.close(); } finally { os.close(); } } finally { handle.finish(); } return true; } private static boolean scanForFiles(File root, List<String> files, String prefix, ProgressHandle handle, AtomicBoolean canceled, boolean mixedSharability) throws IOException { File[] kids = root.listFiles(); if (kids == null) { throw new IOException("could not list " + root); } Arrays.sort(kids); boolean atLeastOneIncluded = false; for (File kid : kids) { if (canceled.get()) { return false; } if (!VisibilityQuery.getDefault().isVisible(kid)) { continue; } //TODO: move to project if (kid.getName().endsWith(".lock.db")) { continue; } boolean kidMixed; if (mixedSharability) { switch (SharabilityQuery.getSharability(Utilities.toURI(kid))) { case SHARABLE: kidMixed = false; break; case NOT_SHARABLE: continue; default: kidMixed = true; } } else { kidMixed = false; } String n = kid.getName(); String prefixN = prefix + n; if (kid.isFile()) { files.add(prefixN); atLeastOneIncluded = true; } else if (kid.isDirectory()) { handle.progress("Searching in " + prefixN); atLeastOneIncluded = scanForFiles(kid, files, prefixN + '/', handle, canceled, kidMixed); } // else symlink etc.? } if (!atLeastOneIncluded && prefix.endsWith("/")) { files.add(prefix); //ends with / atLeastOneIncluded = true; } return atLeastOneIncluded; } private static void writeEntry(String name, Set<String> written, ZipOutputStream zos, File f) throws IOException, FileNotFoundException { if (!written.add(name)) { return; } int idx = name.lastIndexOf('/', name.length() - 2); if (idx != -1) { writeEntry(name.substring(0, idx + 1), written, zos, f.getParentFile()); } ZipEntry ze = new ZipEntry(name); ze.setTime(f.lastModified()); if (name.endsWith("/")) { ze.setMethod(ZipEntry.STORED); ze.setSize(0); ze.setCrc(0); zos.putNextEntry(ze); } else { ByteArrayOutputStream content = new ByteArrayOutputStream((int) f.length()); InputStream is = new FileInputStream(f); try { FileUtil.copy(is, content); } finally { is.close(); } ze.setMethod(ZipEntry.DEFLATED); ze.setSize(f.length()); CRC32 crc = new CRC32(); byte[] data = content.toByteArray(); crc.update(data); ze.setCrc(crc.getValue()); zos.putNextEntry(ze); zos.write(data); } } public static void unpackAndActivateFirst(File zip, File root) throws IOException { final AtomicBoolean canceled = new AtomicBoolean(); List<Project> projects = new ArrayList<Project>(); ProgressHandle handle = ProgressHandleFactory.createHandle("Unpacking " + (zip.getName()), new Cancellable() { @Override public boolean cancel() { return canceled.compareAndSet(false, true); } }); handle.start(); try { List<File> folders = new ArrayList<File>(); InputStream is = new FileInputStream(zip); try { ZipInputStream zis = new ZipInputStream(is); ZipEntry entry; while ((entry = zis.getNextEntry()) != null) { if (canceled.get()) { return; } String n = entry.getName(); File f = new File(root, n); if (n.endsWith("/")) { if (!f.isDirectory()) { if (!f.mkdirs()) { throw new IOException("could not make " + f); } if (entry.getTime() > 0) { if (!f.setLastModified(entry.getTime())) { // oh well } } } folders.add(f); } else { handle.progress("Creating " + (n)); File p = f.getParentFile(); if (!p.isDirectory() && !p.mkdirs()) { throw new IOException("could not make " + p); } OutputStream os = new FileOutputStream(f); try { FileUtil.copy(zis, os); } finally { os.close(); } if (entry.getTime() > 0) { if (!f.setLastModified(entry.getTime())) { // oh well } } } } } finally { is.close(); } handle.switchToDeterminate(folders.size()); for (int i = 0; i < folders.size(); i++) { if (canceled.get()) { return; } File folder = folders.get(i); handle.progress("Checking for project: " + (folder), i); // FileObject fo = FileUtil.toFileObject(folder); //if (fo != null) { // Project p = ProjectManager.getDefault().findProject(fo); // if (p != null) { // projects.add(p); // } //} } } finally { handle.finish(); } //OpenProjects.getDefault().open(projects.toArray(new Project[projects.size()]), false, true); // if (projects.size() > 0) { // Project project = projects.get(0); // if (project instanceof EditableProject) { // final EditableProject ep = (EditableProject) project; //// Logger.getLogger(SystemUtil.class.getName()).info("set editing project"); // EditingProjectService service = EditingProjectService.getInsance(); // service.setEditingProject(ep); // } // } } }