1 19 20 package org.netbeans.modules.versioning.system.cvss.ui.actions.diff; 21 22 import org.netbeans.modules.versioning.system.cvss.FileInformation; 23 import org.netbeans.modules.versioning.system.cvss.ExecutorGroup; 24 import org.netbeans.modules.versioning.system.cvss.CvsModuleConfig; 25 import org.netbeans.modules.versioning.system.cvss.util.Context; 26 import org.netbeans.modules.versioning.util.AccessibleJFileChooser; 27 import org.netbeans.modules.versioning.util.Utils; 28 import org.netbeans.modules.versioning.system.cvss.ui.actions.AbstractSystemAction; 29 import org.netbeans.modules.diff.builtin.visualizer.TextDiffVisualizer; 30 import org.netbeans.api.diff.Difference; 31 import org.netbeans.spi.diff.DiffProvider; 32 import org.openide.windows.TopComponent; 33 import org.openide.util.Lookup; 34 import org.openide.util.RequestProcessor; 35 import org.openide.util.NbBundle; 36 import org.openide.ErrorManager; 37 import org.openide.NotifyDescriptor; 38 import org.openide.DialogDisplayer; 39 import org.openide.DialogDescriptor; 40 import org.openide.nodes.Node; 41 import org.openide.awt.StatusDisplayer; 42 43 import javax.swing.*; 44 import java.io.*; 45 import java.util.*; 46 import java.util.List ; 47 import java.awt.event.ActionListener ; 48 import java.awt.event.ActionEvent ; 49 import java.awt.*; 50 51 64 public class ExportDiffAction extends AbstractSystemAction { 65 66 private static final int enabledForStatus = 67 FileInformation.STATUS_VERSIONED_MERGE | 68 FileInformation.STATUS_VERSIONED_MODIFIEDLOCALLY | 69 FileInformation.STATUS_VERSIONED_DELETEDLOCALLY | 70 FileInformation.STATUS_VERSIONED_REMOVEDLOCALLY | 71 FileInformation.STATUS_NOTVERSIONED_NEWLOCALLY | 72 FileInformation.STATUS_VERSIONED_ADDEDLOCALLY; 73 74 public ExportDiffAction() { 75 setIcon(null); 76 putValue("noIconInMenu", Boolean.TRUE); } 78 79 protected String getBaseName(Node [] activatedNodes) { 80 return "CTL_MenuItem_ExportDiff"; } 82 83 86 public String getName() { 87 TopComponent activated = TopComponent.getRegistry().getActivated(); 88 if (activated instanceof DiffSetupSource) { 89 String setupName = ((DiffSetupSource)activated).getSetupDisplayName(); 90 if (setupName != null) { 91 return NbBundle.getMessage(this.getClass(), getBaseName(getActivatedNodes()) + "_Context", setupName); 93 } 94 } 95 return super.getName(); 96 } 97 98 protected int getFileEnabledStatus() { 99 return enabledForStatus; 100 } 101 102 public boolean enable(Node[] nodes) { 103 TopComponent activated = TopComponent.getRegistry().getActivated(); 104 if (activated instanceof DiffSetupSource) { 105 return true; 106 } 107 return super.enable(nodes) && 108 Lookup.getDefault().lookup(DiffProvider.class) != null; 109 } 110 111 public void performCvsAction(final Node[] nodes) { 112 113 115 boolean noop; 116 TopComponent activated = TopComponent.getRegistry().getActivated(); 117 if (activated instanceof DiffSetupSource) { 118 noop = ((DiffSetupSource) activated).getSetups().isEmpty(); 119 } else { 120 Context context = getContext(nodes); 121 File [] files = DiffExecutor.getModifiedFiles(context, FileInformation.STATUS_LOCAL_CHANGE); 122 noop = files.length == 0; 123 } 124 if (noop) { 125 NotifyDescriptor msg = new NotifyDescriptor.Message(NbBundle.getMessage(ExportDiffAction.class, "BK3001"), NotifyDescriptor.INFORMATION_MESSAGE); 126 DialogDisplayer.getDefault().notify(msg); 127 return; 128 } 129 130 final JFileChooser chooser = new AccessibleJFileChooser(NbBundle.getMessage(ExportDiffAction.class, "ACSD_Export")); 131 chooser.setDialogTitle(NbBundle.getMessage(ExportDiffAction.class, "CTL_Export_Title")); 132 chooser.setMultiSelectionEnabled(false); 133 javax.swing.filechooser.FileFilter [] old = chooser.getChoosableFileFilters(); 134 for (int i = 0; i < old.length; i++) { 135 javax.swing.filechooser.FileFilter fileFilter = old[i]; 136 chooser.removeChoosableFileFilter(fileFilter); 137 138 } 139 chooser.setCurrentDirectory(new File(CvsModuleConfig.getDefault().getPreferences().get("ExportDiff.saveFolder", System.getProperty("user.home")))); chooser.addChoosableFileFilter(new javax.swing.filechooser.FileFilter () { 141 public boolean accept(File f) { 142 return f.getName().endsWith("diff") || f.getName().endsWith("patch") || f.isDirectory(); } 144 public String getDescription() { 145 return NbBundle.getMessage(ExportDiffAction.class, "BK3002"); 146 } 147 }); 148 149 chooser.setDialogType( JFileChooser.SAVE_DIALOG ); chooser.setApproveButtonMnemonic(NbBundle.getMessage(ExportDiffAction.class, "MNE_Export_ExportAction").charAt(0)); 151 chooser.setApproveButtonText(NbBundle.getMessage(ExportDiffAction.class, "CTL_Export_ExportAction")); 152 DialogDescriptor dd = new DialogDescriptor(chooser, NbBundle.getMessage(ExportDiffAction.class, "CTL_Export_Title")); 153 dd.setOptions(new Object [0]); 154 final Dialog dialog = DialogDisplayer.getDefault().createDialog(dd); 155 156 chooser.addActionListener(new ActionListener () { 157 public void actionPerformed(ActionEvent e) { 158 String state = (String )e.getActionCommand(); 159 if (state.equals(JFileChooser.APPROVE_SELECTION)) { 160 File destination = chooser.getSelectedFile(); 161 String name = destination.getName(); 162 boolean requiredExt = false; 163 requiredExt |= name.endsWith(".diff"); requiredExt |= name.endsWith(".dif"); requiredExt |= name.endsWith(".patch"); if (requiredExt == false) { 167 File parent = destination.getParentFile(); 168 destination = new File(parent, name + ".patch"); } 170 171 if (destination.exists()) { 172 NotifyDescriptor nd = new NotifyDescriptor.Confirmation(NbBundle.getMessage(ExportDiffAction.class, "BK3005", destination.getAbsolutePath())); 173 nd.setOptionType(NotifyDescriptor.YES_NO_OPTION); 174 DialogDisplayer.getDefault().notify(nd); 175 if (nd.getValue().equals(NotifyDescriptor.OK_OPTION) == false) { 176 return; 177 } 178 } 179 180 CvsModuleConfig.getDefault().getPreferences().put("ExportDiff.saveFolder", destination.getParent()); 181 182 final File out = destination; 183 RequestProcessor.getDefault().post(new Runnable () { 184 public void run() { 185 async(nodes, out); 186 } 187 }); 188 } 189 dialog.dispose(); 190 } 191 }); 192 dialog.setVisible(true); 193 194 } 195 196 protected boolean asynchronous() { 197 return false; 198 } 199 200 private void async(Node[] nodes, File destination) { 201 boolean success = false; 202 OutputStream out = null; 203 int exportedFiles = 0; 204 ExecutorGroup group = new ExecutorGroup(getRunningName(nodes)); 205 try { 206 207 209 File root; 210 Collection setups; 211 212 TopComponent activated = TopComponent.getRegistry().getActivated(); 213 if (activated instanceof DiffSetupSource) { 214 setups = ((DiffSetupSource) activated).getSetups(); 215 List setupFiles = new ArrayList(setups.size()); 216 for (Iterator i = setups.iterator(); i.hasNext();) { 217 Setup setup = (Setup) i.next(); 218 setupFiles.add(setup.getBaseFile()); 219 } 220 root = getCommonParent((File[]) setupFiles.toArray(new File[setupFiles.size()])); 221 } else { 222 Context context = getContext(nodes); 223 File [] files = DiffExecutor.getModifiedFiles(context, FileInformation.STATUS_LOCAL_CHANGE); 224 root = getCommonParent(context.getRootFiles()); 225 setups = new ArrayList(files.length); 226 for (int i = 0; i < files.length; i++) { 227 File file = files[i]; 228 Setup setup = new Setup(file, Setup.DIFFTYPE_LOCAL); 229 setups.add(setup); 230 } 231 } 232 if (root == null) { 233 NotifyDescriptor nd = new NotifyDescriptor( 234 NbBundle.getMessage(ExportDiffAction.class, "MSG_BadSelection_Prompt"), 235 NbBundle.getMessage(ExportDiffAction.class, "MSG_BadSelection_Title"), 236 NotifyDescriptor.DEFAULT_OPTION, NotifyDescriptor.ERROR_MESSAGE, null, null); 237 DialogDisplayer.getDefault().notify(nd); 238 return; 239 } 240 241 String sep = System.getProperty("line.separator"); out = new BufferedOutputStream(new FileOutputStream(destination)); 243 out.write(("# This patch file was generated by NetBeans IDE" + sep).getBytes("utf8")); out.write(("# Following Index: paths are relative to: " + root.getAbsolutePath() + sep).getBytes("utf8")); out.write(("# This patch can be applied using context Tools: Patch action on respective folder." + sep).getBytes("utf8")); out.write(("# It uses platform neutral UTF-8 encoding and \\n newlines." + sep).getBytes("utf8")); out.write(("# Above lines and this line are ignored by the patching process." + sep).getBytes("utf8")); 250 251 Iterator it = setups.iterator(); 252 int i = 0; 253 while (it.hasNext()) { 254 Setup setup = (Setup) it.next(); 255 File file = setup.getBaseFile(); 256 group.progress(file.getName()); 257 258 String index = "Index: "; String rootPath = root.getAbsolutePath(); 260 String filePath = file.getAbsolutePath(); 261 if (filePath.startsWith(rootPath)) { 262 index += filePath.substring(rootPath.length() + 1).replace(File.separatorChar, '/') + sep; 263 out.write(index.getBytes("utf8")); } 265 exportDiff(group, setup, out); 266 i++; 267 } 268 269 exportedFiles = i; 270 success = true; 271 } catch (IOException ex) { 272 ErrorManager.getDefault().annotate(ex, NbBundle.getMessage(ExportDiffAction.class, "BK3003")); 273 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex); ErrorManager.getDefault().notify(ErrorManager.USER, ex); } finally { 276 group.executed(); 277 if (out != null) { 278 try { 279 out.flush(); 280 out.close(); 281 } catch (IOException alreadyClsoed) { 282 } 283 } 284 if (success) { 285 StatusDisplayer.getDefault().setStatusText(NbBundle.getMessage(ExportDiffAction.class, "BK3004", new Integer (exportedFiles))); 286 if (exportedFiles == 0) { 287 destination.delete(); 288 } 289 } else { 290 destination.delete(); 291 } 292 293 } 294 } 295 296 private static File getCommonParent(File [] files) { 297 File root = files[0]; 298 if (root.isFile()) root = root.getParentFile(); 299 for (int i = 1; i < files.length; i++) { 300 root = Utils.getCommonParent(root, files[i]); 301 if (root == null) return null; 302 } 303 return root; 304 } 305 306 307 private void exportDiff(ExecutorGroup group, Setup setup, OutputStream out) throws IOException { 308 setup.initSources(group); 309 DiffProvider diff = (DiffProvider) Lookup.getDefault().lookup(DiffProvider.class); 310 Reader r1 = setup.getFirstSource().createReader(); 311 if (r1 == null) r1 = new StringReader(""); Reader r2 = setup.getSecondSource().createReader(); 313 if (r2 == null) r2 = new StringReader(""); Difference[] differences = diff.computeDiff(r1, r2); 315 316 File file = setup.getBaseFile(); 317 String name = file.getAbsolutePath(); 318 r1 = setup.getFirstSource().createReader(); 319 if (r1 == null) r1 = new StringReader(""); r2 = setup.getSecondSource().createReader(); 321 if (r2 == null) r2 = new StringReader(""); TextDiffVisualizer.TextDiffInfo info = new TextDiffVisualizer.TextDiffInfo( 323 name + " " + setup.getFirstSource().getTitle(), name + " " + setup.getSecondSource().getTitle(), null, 326 null, 327 r1, 328 r2, 329 differences 330 ); 331 info.setContextMode(true, 3); 332 InputStream is = TextDiffVisualizer.differenceToContextDiffText(info); 333 while(true) { 334 int i = is.read(); 335 if (i == -1) break; 336 out.write(i); 337 } 338 } 339 340 } 341 | Popular Tags |