KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > text > correction > CUCorrectionProposal


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11
12 package org.eclipse.jdt.internal.ui.text.correction;
13
14 import java.util.Iterator JavaDoc;
15
16 import org.eclipse.text.edits.MalformedTreeException;
17 import org.eclipse.text.edits.MultiTextEdit;
18 import org.eclipse.text.edits.TextEdit;
19
20 import org.eclipse.core.runtime.CoreException;
21 import org.eclipse.core.runtime.IStatus;
22 import org.eclipse.core.runtime.NullProgressMonitor;
23 import org.eclipse.core.runtime.Status;
24
25 import org.eclipse.swt.events.VerifyEvent;
26 import org.eclipse.swt.graphics.Image;
27 import org.eclipse.swt.graphics.Point;
28
29 import org.eclipse.jface.dialogs.ErrorDialog;
30
31 import org.eclipse.jface.text.BadLocationException;
32 import org.eclipse.jface.text.Document;
33 import org.eclipse.jface.text.DocumentEvent;
34 import org.eclipse.jface.text.IDocument;
35 import org.eclipse.jface.text.IRegion;
36 import org.eclipse.jface.text.ITextViewer;
37 import org.eclipse.jface.text.contentassist.ICompletionProposalExtension2;
38 import org.eclipse.jface.text.contentassist.IContextInformation;
39 import org.eclipse.jface.text.link.ILinkedModeListener;
40 import org.eclipse.jface.text.link.LinkedModeModel;
41 import org.eclipse.jface.text.link.LinkedModeUI;
42 import org.eclipse.jface.text.link.LinkedPosition;
43 import org.eclipse.jface.text.link.LinkedPositionGroup;
44 import org.eclipse.jface.text.link.ProposalPosition;
45 import org.eclipse.jface.text.link.LinkedModeUI.ExitFlags;
46
47 import org.eclipse.ui.IEditorPart;
48 import org.eclipse.ui.IWorkbenchPage;
49 import org.eclipse.ui.texteditor.ITextEditor;
50 import org.eclipse.ui.texteditor.link.EditorLinkedModeUI;
51
52 import org.eclipse.compare.rangedifferencer.IRangeComparator;
53 import org.eclipse.compare.rangedifferencer.RangeDifference;
54 import org.eclipse.compare.rangedifferencer.RangeDifferencer;
55
56 import org.eclipse.ltk.core.refactoring.Change;
57 import org.eclipse.ltk.core.refactoring.DocumentChange;
58 import org.eclipse.ltk.core.refactoring.TextChange;
59 import org.eclipse.ltk.core.refactoring.TextFileChange;
60
61 import org.eclipse.jdt.core.ICompilationUnit;
62 import org.eclipse.jdt.core.JavaModelException;
63
64 import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
65 import org.eclipse.jdt.internal.corext.fix.LinkedProposalPositionGroup;
66 import org.eclipse.jdt.internal.corext.fix.LinkedProposalModel;
67 import org.eclipse.jdt.internal.corext.refactoring.changes.CompilationUnitChange;
68 import org.eclipse.jdt.internal.corext.util.Resources;
69 import org.eclipse.jdt.internal.corext.util.Strings;
70
71 import org.eclipse.jdt.ui.JavaUI;
72 import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal;
73
74 import org.eclipse.jdt.internal.ui.JavaPlugin;
75 import org.eclipse.jdt.internal.ui.JavaUIStatus;
76 import org.eclipse.jdt.internal.ui.compare.JavaTokenComparator;
77 import org.eclipse.jdt.internal.ui.javaeditor.EditorHighlightingSynchronizer;
78 import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility;
79 import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
80 import org.eclipse.jdt.internal.ui.util.ExceptionHandler;
81
82 /**
83  * A proposal for quick fixes and quick assist that work on a single compilation unit.
84  * Either a {@link TextChange text change} is directly passed in the constructor or method
85  * {@link #addEdits(IDocument, TextEdit)} is overridden to provide the text edits that are
86  * applied to the document when the proposal is evaluated.
87  * <p>
88  * The proposal takes care of the preview of the changes as proposal information.
89  * </p>
90  * @since 3.2
91  */

92 public class CUCorrectionProposal extends ChangeCorrectionProposal {
93
94     private ICompilationUnit fCompilationUnit;
95     private LinkedProposalModel fLinkedProposalModel;
96
97
98     /**
99      * Constructs a correction proposal working on a compilation unit with a given text change
100      *
101      * @param name the name that is displayed in the proposal selection dialog.
102      * @param cu the compilation unit on that the change works.
103      * @param change the change that is executed when the proposal is applied or <code>null</code>
104      * if implementors override {@link #addEdits(IDocument, TextEdit)} to provide
105      * the text edits or {@link #createTextChange()} to provide a text change.
106      * @param relevance the relevance of this proposal.
107      * @param image the image that is displayed for this proposal or <code>null</code> if no
108      * image is desired.
109      */

110     public CUCorrectionProposal(String JavaDoc name, ICompilationUnit cu, TextChange change, int relevance, Image image) {
111         super(name, change, relevance, image);
112         if (cu == null) {
113             throw new IllegalArgumentException JavaDoc("Compilation unit must not be null"); //$NON-NLS-1$
114
}
115         fCompilationUnit= cu;
116         fLinkedProposalModel= null;
117     }
118     
119     /**
120      * Constructs a correction proposal working on a compilation unit.
121      * <p>Users have to override {@link #addEdits(IDocument, TextEdit)} to provide
122      * the text edits or {@link #createTextChange()} to provide a text change.
123      * </p>
124      *
125      * @param name The name that is displayed in the proposal selection dialog.
126      * @param cu The compilation unit on that the change works.
127      * @param relevance The relevance of this proposal.
128      * @param image The image that is displayed for this proposal or <code>null</code> if no
129      * image is desired.
130      */

131     protected CUCorrectionProposal(String JavaDoc name, ICompilationUnit cu, int relevance, Image image) {
132         this(name, cu, null, relevance, image);
133     }
134
135     /**
136      * Called when the {@link CompilationUnitChange} is initialized. Subclasses can override to
137      * add text edits to the root edit of the change. Implementors must not access the proposal,
138      * e.g getting the change.
139      * <p>The default implementation does not add any edits</p>
140      *
141      * @param document content of the underlying compilation unit. To be accessed read only.
142      * @param editRoot The root edit to add all edits to
143      * @throws CoreException can be thrown if adding the edits is failing.
144      */

145     protected void addEdits(IDocument document, TextEdit editRoot) throws CoreException {
146         if (false) {
147             throw new CoreException(JavaUIStatus.createError(IStatus.ERROR, "Implementors can throw an exception", null)); //$NON-NLS-1$
148
}
149     }
150     
151     protected LinkedProposalModel getLinkedProposalModel() {
152         if (fLinkedProposalModel == null) {
153             fLinkedProposalModel= new LinkedProposalModel();
154         }
155         return fLinkedProposalModel;
156     }
157     
158     protected void setLinkedProposalModel(LinkedProposalModel model) {
159         fLinkedProposalModel= model;
160     }
161
162     /*
163      * @see ICompletionProposal#getAdditionalProposalInfo()
164      */

165     public String JavaDoc getAdditionalProposalInfo() {
166         StringBuffer JavaDoc buf= new StringBuffer JavaDoc();
167
168         try {
169             TextChange change= getTextChange();
170
171             IDocument previewContent= change.getPreviewDocument(new NullProgressMonitor());
172             String JavaDoc currentConentString= change.getCurrentContent(new NullProgressMonitor());
173
174             /*
175              * Do not change the type of those local variables. We use Object
176              * here in order to prevent loading of the Compare plug-in at load
177              * time of this class.
178              */

179             Object JavaDoc leftSide= new JavaTokenComparator(previewContent.get());
180             Object JavaDoc rightSide= new JavaTokenComparator(currentConentString);
181
182             RangeDifference[] differences= RangeDifferencer.findRanges((IRangeComparator)leftSide, (IRangeComparator)rightSide);
183             for (int i= 0; i < differences.length; i++) {
184                 RangeDifference curr= differences[i];
185                 int start= ((JavaTokenComparator)leftSide).getTokenStart(curr.leftStart());
186                 int end= ((JavaTokenComparator)leftSide).getTokenStart(curr.leftEnd());
187                 if (curr.kind() == RangeDifference.CHANGE && curr.leftLength() > 0) {
188                     buf.append("<b>"); //$NON-NLS-1$
189
appendContent(previewContent, start, end, buf, false);
190                     buf.append("</b>"); //$NON-NLS-1$
191
} else if (curr.kind() == RangeDifference.NOCHANGE) {
192                     appendContent(previewContent, start, end, buf, true);
193                 }
194             }
195         } catch (CoreException e) {
196             JavaPlugin.log(e);
197         } catch (BadLocationException e) {
198             JavaPlugin.log(e);
199         }
200         return buf.toString();
201     }
202
203     private final int surroundLines= 1;
204
205     private void appendContent(IDocument text, int startOffset, int endOffset, StringBuffer JavaDoc buf, boolean surroundLinesOnly) throws BadLocationException {
206         int startLine= text.getLineOfOffset(startOffset);
207         int endLine= text.getLineOfOffset(endOffset);
208
209         boolean dotsAdded= false;
210         if (surroundLinesOnly && startOffset == 0) { // no surround lines for the top no-change range
211
startLine= Math.max(endLine - surroundLines, 0);
212             buf.append("...<br>"); //$NON-NLS-1$
213
dotsAdded= true;
214         }
215
216         for (int i= startLine; i <= endLine; i++) {
217             if (surroundLinesOnly) {
218                 if ((i - startLine > surroundLines) && (endLine - i > surroundLines)) {
219                     if (!dotsAdded) {
220                         buf.append("...<br>"); //$NON-NLS-1$
221
dotsAdded= true;
222                     } else if (endOffset == text.getLength()) {
223                         return; // no surround lines for the bottom no-change range
224
}
225                     continue;
226                 }
227             }
228
229             IRegion lineInfo= text.getLineInformation(i);
230             int start= lineInfo.getOffset();
231             int end= start + lineInfo.getLength();
232
233             int from= Math.max(start, startOffset);
234             int to= Math.min(end, endOffset);
235             String JavaDoc content= text.get(from, to - from);
236             if (surroundLinesOnly && (from == start) && Strings.containsOnlyWhitespaces(content)) {
237                 continue; // ignore empty lines except when range started in the middle of a line
238
}
239             for (int k= 0; k < content.length(); k++) {
240                 char ch= content.charAt(k);
241                 if (ch == '<') {
242                     buf.append("&lt;"); //$NON-NLS-1$
243
} else if (ch == '>') {
244                     buf.append("&gt;"); //$NON-NLS-1$
245
} else {
246                     buf.append(ch);
247                 }
248             }
249             if (to == end && to != endOffset) { // new line when at the end of the line, and not end of range
250
buf.append("<br>"); //$NON-NLS-1$
251
}
252         }
253     }
254
255     /* (non-Javadoc)
256      * @see org.eclipse.jface.text.contentassist.ICompletionProposal#apply(org.eclipse.jface.text.IDocument)
257      */

258     public void apply(IDocument document) {
259         try {
260             ICompilationUnit unit= getCompilationUnit();
261             IEditorPart part= null;
262             if (unit.getResource().exists()) {
263                 boolean canEdit= performValidateEdit(unit);
264                 if (!canEdit) {
265                     return;
266                 }
267                 part= EditorUtility.isOpenInEditor(unit);
268                 if (part == null) {
269                     part= JavaUI.openInEditor(unit);
270                     if (part != null) {
271                         document= JavaUI.getDocumentProvider().getDocument(part.getEditorInput());
272                     }
273                 }
274                 IWorkbenchPage page= JavaPlugin.getActivePage();
275                 if (page != null && part != null) {
276                     page.bringToTop(part);
277                 }
278                 if (part != null) {
279                     part.setFocus();
280                 }
281             }
282             performChange(part, document);
283         } catch (CoreException e) {
284             ExceptionHandler.handle(e, CorrectionMessages.CUCorrectionProposal_error_title, CorrectionMessages.CUCorrectionProposal_error_message);
285         }
286     }
287
288     private boolean performValidateEdit(ICompilationUnit unit) {
289         IStatus status= Resources.makeCommittable(unit.getResource(), JavaPlugin.getActiveWorkbenchShell());
290         if (!status.isOK()) {
291             String JavaDoc label= CorrectionMessages.CUCorrectionProposal_error_title;
292             String JavaDoc message= CorrectionMessages.CUCorrectionProposal_error_message;
293             ErrorDialog.openError(JavaPlugin.getActiveWorkbenchShell(), label, message, status);
294             return false;
295         }
296         return true;
297     }
298     
299     /* (non-Javadoc)
300      * @see org.eclipse.jdt.internal.ui.text.correction.ChangeCorrectionProposal#performChange(org.eclipse.jface.text.IDocument, org.eclipse.ui.IEditorPart)
301      */

302     protected void performChange(IEditorPart part, IDocument document) throws CoreException {
303         try {
304             super.performChange(part, document);
305             if (part == null) {
306                 return;
307             }
308
309             if (fLinkedProposalModel != null) {
310                 if (fLinkedProposalModel.hasLinkedPositions() && part instanceof JavaEditor) {
311                     // enter linked mode
312
ITextViewer viewer= ((JavaEditor) part).getViewer();
313                     enterLinkedMode(viewer, part);
314                 } else if (part instanceof ITextEditor) {
315                     LinkedProposalPositionGroup.PositionInformation endPosition= fLinkedProposalModel.getEndPosition();
316                     if (endPosition != null) {
317                         // select a result
318
int pos= endPosition.getOffset() + endPosition.getLength();
319                         ((ITextEditor) part).selectAndReveal(pos, 0);
320                     }
321                 }
322             }
323         } catch (BadLocationException e) {
324             throw new CoreException(JavaUIStatus.createError(IStatus.ERROR, e));
325         }
326
327     }
328
329     private void enterLinkedMode(ITextViewer viewer, IEditorPart editor) throws BadLocationException {
330         IDocument document= viewer.getDocument();
331
332         LinkedModeModel model= new LinkedModeModel();
333         boolean added= false;
334         
335         Iterator JavaDoc iterator= fLinkedProposalModel.getPositionGroupIterator();
336         while (iterator.hasNext()) {
337             LinkedProposalPositionGroup curr= (LinkedProposalPositionGroup) iterator.next();
338             
339             LinkedPositionGroup group= new LinkedPositionGroup();
340             
341             LinkedProposalPositionGroup.PositionInformation[] positions= curr.getPositions();
342             if (positions.length > 0) {
343                 LinkedProposalPositionGroup.Proposal[] linkedModeProposals= curr.getProposals();
344                 if (linkedModeProposals.length <= 1) {
345                     for (int i= 0; i < positions.length; i++) {
346                         LinkedProposalPositionGroup.PositionInformation pos= positions[i];
347                         if (pos.getOffset() != -1) {
348                             group.addPosition(new LinkedPosition(document, pos.getOffset(), pos.getLength(), pos.getSequenceRank()));
349                         }
350                     }
351                 } else {
352                     LinkedPositionProposalImpl[] proposalImpls= new LinkedPositionProposalImpl[linkedModeProposals.length];
353                     for (int i= 0; i < linkedModeProposals.length; i++) {
354                         proposalImpls[i]= new LinkedPositionProposalImpl(linkedModeProposals[i], model);
355                     }
356                     
357                     for (int i= 0; i < positions.length; i++) {
358                         LinkedProposalPositionGroup.PositionInformation pos= positions[i];
359                         if (pos.getOffset() != -1) {
360                             group.addPosition(new ProposalPosition(document, pos.getOffset(), pos.getLength(), pos.getSequenceRank(), proposalImpls));
361                         }
362                     }
363                 }
364                 model.addGroup(group);
365                 added= true;
366             }
367         }
368
369         model.forceInstall();
370
371         if (editor instanceof JavaEditor) {
372             model.addLinkingListener(new EditorHighlightingSynchronizer((JavaEditor) editor));
373         }
374
375         if (added) { // only set up UI if there are any positions set
376
LinkedModeUI ui= new EditorLinkedModeUI(model, viewer);
377             LinkedProposalPositionGroup.PositionInformation endPosition= fLinkedProposalModel.getEndPosition();
378             if (endPosition != null && endPosition.getOffset() != -1) {
379                 ui.setExitPosition(viewer, endPosition.getOffset() + endPosition.getLength(), 0, Integer.MAX_VALUE);
380             } else {
381                 int cursorPosition= viewer.getSelectedRange().x;
382                 if (cursorPosition != 0) {
383                     ui.setExitPosition(viewer, cursorPosition, 0, Integer.MAX_VALUE);
384                 }
385             }
386             ui.setExitPolicy(new LinkedModeExitPolicy());
387             ui.enter();
388
389             IRegion region= ui.getSelectedRegion();
390             viewer.setSelectedRange(region.getOffset(), region.getLength());
391             viewer.revealRange(region.getOffset(), region.getLength());
392         }
393     }
394
395     
396     /**
397      * Creates the text change for this proposal.
398      * This method is only called once and only when no text change has been passed in
399      * {@link #CUCorrectionProposal(String, ICompilationUnit, TextChange, int, Image)}.
400      *
401      * @return returns the created text change.
402      * @throws CoreException thrown if the creation of the text change failed.
403      */

404     protected TextChange createTextChange() throws CoreException {
405         ICompilationUnit cu= getCompilationUnit();
406         String JavaDoc name= getName();
407         TextChange change;
408         if (!cu.getResource().exists()) {
409             String JavaDoc source;
410             try {
411                 source= cu.getSource();
412             } catch (JavaModelException e) {
413                 JavaPlugin.log(e);
414                 source= new String JavaDoc(); // empty
415
}
416             Document document= new Document(source);
417             document.setInitialLineDelimiter(StubUtility.getLineDelimiterUsed(cu));
418             change= new DocumentChange(name, document);
419         } else {
420             CompilationUnitChange cuChange = new CompilationUnitChange(name, cu);
421             cuChange.setSaveMode(TextFileChange.LEAVE_DIRTY);
422             change= cuChange;
423         }
424         TextEdit rootEdit= new MultiTextEdit();
425         change.setEdit(rootEdit);
426
427         // initialize text change
428
IDocument document= change.getCurrentDocument(new NullProgressMonitor());
429         addEdits(document, rootEdit);
430         return change;
431     }
432         
433     
434     /* (non-Javadoc)
435      * @see org.eclipse.jdt.internal.ui.text.correction.ChangeCorrectionProposal#createChange()
436      */

437     protected final Change createChange() throws CoreException {
438         return createTextChange(); // make sure that only text changes are allowed here
439
}
440     
441     /**
442      * Gets the text change that is invoked when the change is applied.
443      *
444      * @return returns the text change that is invoked when the change is applied.
445      * @throws CoreException throws an exception if accessing the change failed
446      */

447     public final TextChange getTextChange() throws CoreException {
448         return (TextChange) getChange();
449     }
450
451     /**
452      * The compilation unit on that the change works.
453      *
454      * @return the compilation unit on that the change works.
455      */

456     public final ICompilationUnit getCompilationUnit() {
457         return fCompilationUnit;
458     }
459
460     /**
461      * Creates a preview of the content of the compilation unit after applying the change.
462      *
463      * @return returns the preview of the changed compilation unit.
464      * @throws CoreException thrown if the creation of the change failed.
465      */

466     public String JavaDoc getPreviewContent() throws CoreException {
467         return getTextChange().getPreviewContent(new NullProgressMonitor());
468     }
469
470     /* (non-Javadoc)
471      * @see java.lang.Object#toString()
472      */

473     public String JavaDoc toString() {
474         try {
475             return getPreviewContent();
476         } catch (CoreException e) {
477         }
478         return super.toString();
479     }
480         
481
482     private static class LinkedModeExitPolicy implements LinkedModeUI.IExitPolicy {
483         public ExitFlags doExit(LinkedModeModel model, VerifyEvent event, int offset, int length) {
484             if (event.character == '=') {
485                 return new ExitFlags(ILinkedModeListener.EXIT_ALL, true);
486             }
487             return null;
488         }
489     }
490     
491     private static class LinkedPositionProposalImpl implements ICompletionProposalExtension2, IJavaCompletionProposal {
492
493         private final LinkedProposalPositionGroup.Proposal fProposal;
494         private final LinkedModeModel fLinkedPositionModel;
495         
496
497         public LinkedPositionProposalImpl(LinkedProposalPositionGroup.Proposal proposal, LinkedModeModel model) {
498             fProposal= proposal;
499             fLinkedPositionModel= model;
500         }
501
502         /* (non-Javadoc)
503          * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#apply(org.eclipse.jface.text.ITextViewer, char, int, int)
504          */

505         public void apply(ITextViewer viewer, char trigger, int stateMask, int offset) {
506             IDocument doc= viewer.getDocument();
507             LinkedPosition position= fLinkedPositionModel.findPosition(new LinkedPosition(doc, offset, 0));
508             if (position != null) {
509                 try {
510                     try {
511                         TextEdit edit= fProposal.computeEdits(offset, position, trigger, stateMask, fLinkedPositionModel);
512                         if (edit != null) {
513                             edit.apply(position.getDocument(), 0);
514                         }
515                     } catch (MalformedTreeException e) {
516                         throw new CoreException(new Status(IStatus.ERROR, JavaUI.ID_PLUGIN, IStatus.ERROR, "Unexpected exception applying edit", e)); //$NON-NLS-1$
517
} catch (BadLocationException e) {
518                         throw new CoreException(new Status(IStatus.ERROR, JavaUI.ID_PLUGIN, IStatus.ERROR, "Unexpected exception applying edit", e)); //$NON-NLS-1$
519
}
520                 } catch (CoreException e) {
521                     JavaPlugin.log(e);
522                 }
523             }
524         }
525
526         /* (non-Javadoc)
527          * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getDisplayString()
528          */

529         public String JavaDoc getDisplayString() {
530             return fProposal.getDisplayString();
531         }
532
533         /* (non-Javadoc)
534          * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getImage()
535          */

536         public Image getImage() {
537             return fProposal.getImage();
538         }
539
540         /* (non-Javadoc)
541          * @see org.eclipse.jdt.ui.text.java.IJavaCompletionProposal#getRelevance()
542          */

543         public int getRelevance() {
544             return fProposal.getRelevance();
545         }
546
547         /* (non-Javadoc)
548          * @see org.eclipse.jface.text.contentassist.ICompletionProposal#apply(org.eclipse.jface.text.IDocument)
549          */

550         public void apply(IDocument document) {
551             // not called
552
}
553         
554         /* (non-Javadoc)
555          * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getAdditionalProposalInfo()
556          */

557         public String JavaDoc getAdditionalProposalInfo() {
558             return fProposal.getAdditionalProposalInfo();
559         }
560
561         public Point getSelection(IDocument document) { return null; }
562         public IContextInformation getContextInformation() { return null; }
563         public void selected(ITextViewer viewer, boolean smartToggle) {}
564         public void unselected(ITextViewer viewer) {}
565
566         /*
567          * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#validate(org.eclipse.jface.text.IDocument, int, org.eclipse.jface.text.DocumentEvent)
568          */

569         public boolean validate(IDocument document, int offset, DocumentEvent event) {
570             // ignore event
571
String JavaDoc insert= getDisplayString();
572
573             int off;
574             LinkedPosition pos= fLinkedPositionModel.findPosition(new LinkedPosition(document, offset, 0));
575             if (pos != null) {
576                 off= pos.getOffset();
577             } else {
578                 off= Math.max(0, offset - insert.length());
579             }
580             int length= offset - off;
581
582             if (offset <= document.getLength()) {
583                 try {
584                     String JavaDoc content= document.get(off, length);
585                     if (insert.startsWith(content))
586                         return true;
587                 } catch (BadLocationException e) {
588                     JavaPlugin.log(e);
589                     // and ignore and return false
590
}
591             }
592             return false;
593         }
594     }
595 }
596
Popular Tags