PageRenderTime 77ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/netbeans-7.3/git/src/org/netbeans/modules/git/ui/history/DiffResultsViewForLine.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 321 lines | 243 code | 29 blank | 49 comment | 56 complexity | 79c8a835ba5afe9a1ed02bd783e850dc MD5 | raw file
  1. /*
  2. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  3. *
  4. * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
  5. *
  6. * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  7. * Other names may be trademarks of their respective owners.
  8. *
  9. * The contents of this file are subject to the terms of either the GNU
  10. * General Public License Version 2 only ("GPL") or the Common
  11. * Development and Distribution License("CDDL") (collectively, the
  12. * "License"). You may not use this file except in compliance with the
  13. * License. You can obtain a copy of the License at
  14. * http://www.netbeans.org/cddl-gplv2.html
  15. * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  16. * specific language governing permissions and limitations under the
  17. * License. When distributing the software, include this License Header
  18. * Notice in each file and include the License file at
  19. * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
  20. * particular file as subject to the "Classpath" exception as provided
  21. * by Oracle in the GPL Version 2 section of the License file that
  22. * accompanied this code. If applicable, add the following below the
  23. * License Header, with the fields enclosed by brackets [] replaced by
  24. * your own identifying information:
  25. * "Portions Copyrighted [year] [name of copyright owner]"
  26. *
  27. * If you wish your version of this file to be governed by only the CDDL
  28. * or only the GPL Version 2, indicate your decision by adding
  29. * "[Contributor] elects to include this software in this distribution
  30. * under the [CDDL or GPL Version 2] license." If you do not indicate a
  31. * single choice of license, a recipient has the option to distribute
  32. * your version of this file under either the CDDL, the GPL Version 2 or
  33. * to extend the choice of license to its licensees as provided above.
  34. * However, if you add GPL Version 2 code and therefore, elected the GPL
  35. * Version 2 license, then the option applies only if the new code is
  36. * made subject to such option by the copyright holder.
  37. *
  38. * Contributor(s):
  39. *
  40. * Portions Copyrighted 2009 Sun Microsystems, Inc.
  41. */
  42. package org.netbeans.modules.git.ui.history;
  43. import java.io.File;
  44. import java.io.IOException;
  45. import java.io.Reader;
  46. import java.io.Writer;
  47. import java.util.List;
  48. import java.util.logging.Level;
  49. import javax.swing.SwingUtilities;
  50. import javax.swing.text.DefaultStyledDocument;
  51. import javax.swing.text.Document;
  52. import javax.swing.text.EditorKit;
  53. import javax.swing.text.StyleContext;
  54. import javax.swing.text.StyledDocument;
  55. import javax.swing.text.StyledEditorKit;
  56. import org.netbeans.api.diff.DiffController;
  57. import org.netbeans.api.diff.Difference;
  58. import org.netbeans.api.diff.StreamSource;
  59. import org.netbeans.modules.git.client.GitProgressSupport;
  60. import org.netbeans.modules.git.ui.diff.DiffStreamSource;
  61. import org.netbeans.modules.git.ui.history.RepositoryRevision.Event;
  62. import org.netbeans.modules.git.utils.GitUtils;
  63. import org.netbeans.modules.versioning.util.Utils;
  64. import org.openide.cookies.EditorCookie;
  65. import org.openide.filesystems.FileObject;
  66. import org.openide.filesystems.FileUtil;
  67. import org.openide.loaders.DataObject;
  68. import org.openide.text.CloneableEditorSupport;
  69. import org.openide.util.Lookup;
  70. import org.openide.util.NbBundle;
  71. import org.openide.util.lookup.Lookups;
  72. /**
  73. * DiffResultsView not showing differences but rather fixed line numbers.
  74. * Currently used by bugtracking to display revisions of a file and to fix the view on a given line number.
  75. *
  76. * @author Ondra Vrabec
  77. */
  78. final class DiffResultsViewForLine extends DiffResultsView {
  79. private int lineNumber;
  80. public DiffResultsViewForLine(final SearchHistoryPanel parent, final List<RepositoryRevision> results, final int lineNumber) {
  81. super(parent, results);
  82. this.lineNumber = Math.max(lineNumber - 1, 0);
  83. setButtonLabels();
  84. }
  85. @Override
  86. protected void showRevisionDiff(RepositoryRevision.Event rev, boolean showLastDifference) {
  87. if (rev.getFile() == null) return;
  88. showDiff(rev.getLogInfoHeader().getRepositoryRoot(), null, rev, showLastDifference);
  89. }
  90. @Override
  91. protected GitProgressSupport createShowDiffTask (Event revision1, Event revision2, boolean showLastDifference) {
  92. if (revision1 == null) {
  93. return new ShowDiffTask(revision2.getFile(), revision2.getLogInfoHeader().getLog().getRevision(), showLastDifference);
  94. } else {
  95. return super.createShowDiffTask(revision1, revision2, showLastDifference);
  96. }
  97. }
  98. @Override
  99. void onNextButton() {
  100. if (++currentIndex >= treeView.getRowCount()) currentIndex = 0;
  101. setDiffIndex(currentIndex, false);
  102. }
  103. @Override
  104. void onPrevButton() {
  105. if (--currentIndex < 0) currentIndex = treeView.getRowCount() - 1;
  106. setDiffIndex(currentIndex, true);
  107. }
  108. private void setButtonLabels() {
  109. parent.bNext.getAccessibleContext().setAccessibleName(NbBundle.getMessage(DiffResultsViewForLine.class, "ACSN_NextRevision")); // NOI18N
  110. parent.bNext.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(DiffResultsViewForLine.class, "ACSD_NextRevision")); // NOI18N
  111. parent.bNext.setToolTipText(NbBundle.getMessage(DiffResultsViewForLine.class, "ACSD_NextRevision")); // NOI18N
  112. parent.bPrev.getAccessibleContext().setAccessibleName(NbBundle.getMessage(DiffResultsViewForLine.class, "ACSN_PrevRevision")); // NOI18N
  113. parent.bPrev.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(DiffResultsViewForLine.class, "ACSD_PrevRevision")); // NOI18N
  114. parent.bPrev.setToolTipText(NbBundle.getMessage(DiffResultsViewForLine.class, "ACSD_PrevRevision")); // NOI18N
  115. }
  116. private class ShowDiffTask extends GitProgressSupport {
  117. private final File file;
  118. private final String revision;
  119. public ShowDiffTask (File file, String revision, boolean showLastDifference) {
  120. this.file = file;
  121. this.revision = revision;
  122. }
  123. @Override
  124. public void perform () {
  125. showDiffError(NbBundle.getMessage(DiffResultsView.class, "MSG_DiffPanel_LoadingDiff")); //NOI18N
  126. final DiffStreamSource leftSource = new DiffStreamSource(file, revision, revision);
  127. final LocalFileDiffStreamSource rightSource = new LocalFileDiffStreamSource(file, true);
  128. // it's enqueued at ClientRuntime queue and does not return until previous request handled
  129. leftSource.getMIMEType(); // triggers s1.init()
  130. if (isCanceled()) {
  131. showDiffError(NbBundle.getMessage(DiffResultsView.class, "MSG_DiffPanel_NoRevisions")); // NOI18N
  132. return;
  133. }
  134. rightSource.getMIMEType();
  135. if (isCanceled()) {
  136. showDiffError(NbBundle.getMessage(DiffResultsView.class, "MSG_DiffPanel_NoRevisions")); // NOI18N
  137. return;
  138. }
  139. if (currentTask != this) return;
  140. SwingUtilities.invokeLater(new Runnable() {
  141. @Override
  142. public void run() {
  143. try {
  144. if (isCanceled()) {
  145. showDiffError(NbBundle.getMessage(DiffResultsView.class, "MSG_DiffPanel_NoRevisions")); // NOI18N
  146. return;
  147. }
  148. final DiffController view = DiffController.createEnhanced(leftSource, rightSource);
  149. int leftMaxLineNumber = getLastLineIndex(leftSource);
  150. int rightMaxLineNumber = getLastLineIndex(rightSource);
  151. if (currentTask == ShowDiffTask.this) {
  152. currentDiff = view;
  153. setBottomComponent(currentDiff.getJComponent());
  154. if (leftMaxLineNumber != -1) {
  155. setLocation(Math.min(leftMaxLineNumber, lineNumber), false);
  156. }
  157. if (rightMaxLineNumber != -1) {
  158. setLocation(Math.min(rightMaxLineNumber, lineNumber), true);
  159. }
  160. parent.refreshComponents(false);
  161. }
  162. } catch (IOException e) {
  163. LOG.log(Level.INFO, null, e);
  164. }
  165. }
  166. });
  167. }
  168. }
  169. private int getLastLineIndex (final StreamSource ss) {
  170. String mimeType = ss.getMIMEType();
  171. if (mimeType == null || !mimeType.startsWith("text/")) {
  172. LOG.log(Level.INFO, "Wrong mime type");
  173. return 0;
  174. }
  175. EditorKit kit = CloneableEditorSupport.getEditorKit(mimeType);
  176. if (kit == null) {
  177. LOG.log(Level.WARNING, "No editor kit available");
  178. return 0;
  179. }
  180. Document sdoc = getSourceDocument(ss);
  181. Document doc = sdoc != null ? sdoc : kit.createDefaultDocument();
  182. StyledDocument styledDoc;
  183. if ((doc instanceof StyledDocument)) {
  184. styledDoc = (StyledDocument) doc;
  185. } else {
  186. styledDoc = new DefaultStyledDocument(new StyleContext());
  187. kit = new StyledEditorKit();
  188. }
  189. if (sdoc == null) {
  190. Reader r = null;
  191. try {
  192. r = ss.createReader();
  193. if (r != null) {
  194. try {
  195. kit.read(r, styledDoc, 0);
  196. } catch (javax.swing.text.BadLocationException e) {
  197. throw new IOException("Can not locate the beginning of the document."); // NOI18N
  198. }
  199. }
  200. } catch (IOException ex) {
  201. LOG.log(Level.INFO, null, ex);
  202. } finally {
  203. try {
  204. if (r != null) {
  205. r.close();
  206. }
  207. } catch (IOException ex) {
  208. LOG.log(Level.INFO, null, ex);
  209. }
  210. }
  211. }
  212. return org.openide.text.NbDocument.findLineNumber(styledDoc, styledDoc.getEndPosition().getOffset());
  213. }
  214. private Document getSourceDocument(StreamSource ss) {
  215. Document sdoc = null;
  216. FileObject fo = ss.getLookup().lookup(FileObject.class);
  217. if (fo != null) {
  218. try {
  219. DataObject dao = DataObject.find(fo);
  220. if (dao.getPrimaryFile() == fo) {
  221. EditorCookie ec = dao.getCookie(EditorCookie.class);
  222. if (ec != null) {
  223. sdoc = ec.openDocument();
  224. }
  225. }
  226. } catch (Exception e) {
  227. // fallback to other means of obtaining the source
  228. }
  229. } else {
  230. sdoc = ss.getLookup().lookup(Document.class);
  231. }
  232. return sdoc;
  233. }
  234. private void setLocation (final int lineNumber, final boolean showLineInLocal) {
  235. if (currentDiff == null) {
  236. return;
  237. }
  238. if (showLineInLocal) {
  239. currentDiff.setLocation(DiffController.DiffPane.Modified, DiffController.LocationType.LineNumber, lineNumber);
  240. } else {
  241. currentDiff.getJComponent().putClientProperty("diff.smartScrollDisabled", Boolean.TRUE);
  242. currentDiff.setLocation(DiffController.DiffPane.Base, DiffController.LocationType.LineNumber, lineNumber);
  243. }
  244. }
  245. private static class LocalFileDiffStreamSource extends StreamSource {
  246. private final FileObject fileObject;
  247. private final boolean isRight;
  248. private File file;
  249. private String mimeType;
  250. public LocalFileDiffStreamSource (File file, boolean isRight) {
  251. this.file = FileUtil.normalizeFile(file);
  252. this.fileObject = FileUtil.toFileObject(this.file);
  253. this.isRight = isRight;
  254. }
  255. @Override
  256. public boolean isEditable() {
  257. return isRight && fileObject != null && fileObject.canWrite();
  258. }
  259. @Override
  260. public Lookup getLookup() {
  261. if (fileObject != null) {
  262. return Lookups.fixed(fileObject);
  263. } else {
  264. return Lookups.fixed();
  265. }
  266. }
  267. @Override
  268. public String getName() {
  269. return file.getName();
  270. }
  271. @Override
  272. public String getTitle() {
  273. return fileObject != null ? FileUtil.getFileDisplayName(fileObject) : file.getAbsolutePath();
  274. }
  275. @Override
  276. public String getMIMEType() {
  277. return mimeType = fileObject != null && fileObject.isValid() ? GitUtils.getMimeType(file) : null;
  278. }
  279. @Override
  280. public Reader createReader() throws IOException {
  281. if (mimeType == null || !mimeType.startsWith("text/")) {
  282. return null;
  283. } else {
  284. return Utils.createReader(file);
  285. }
  286. }
  287. @Override
  288. public Writer createWriter(Difference[] conflicts) throws IOException {
  289. return null;
  290. }
  291. }
  292. }