Source Code Cross Referenced for BundleSourcePage.java in  » IDE-Eclipse » Eclipse-plug-in-development » org » eclipse » pde » internal » ui » editor » plugin » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Eclipse » Eclipse plug in development » org.eclipse.pde.internal.ui.editor.plugin 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*******************************************************************************
002:         * Copyright (c) 2003, 2007 IBM Corporation and others.
003:         * All rights reserved. This program and the accompanying materials
004:         * are made available under the terms of the Eclipse Public License v1.0
005:         * which accompanies this distribution, and is available at
006:         * http://www.eclipse.org/legal/epl-v10.html
007:         *
008:         * Contributors:
009:         *     IBM Corporation - initial API and implementation
010:         *******************************************************************************/package org.eclipse.pde.internal.ui.editor.plugin;
011:
012:        import java.util.ArrayList;
013:        import java.util.Iterator;
014:        import java.util.Map;
015:
016:        import org.eclipse.core.runtime.CoreException;
017:        import org.eclipse.jface.action.IMenuManager;
018:        import org.eclipse.jface.text.BadLocationException;
019:        import org.eclipse.jface.text.ITextSelection;
020:        import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
021:        import org.eclipse.jface.viewers.ILabelProvider;
022:        import org.eclipse.jface.viewers.ISelection;
023:        import org.eclipse.jface.viewers.ITreeContentProvider;
024:        import org.eclipse.jface.viewers.LabelProvider;
025:        import org.eclipse.jface.viewers.SelectionChangedEvent;
026:        import org.eclipse.osgi.util.NLS;
027:        import org.eclipse.pde.core.IBaseModel;
028:        import org.eclipse.pde.core.plugin.IPluginLibrary;
029:        import org.eclipse.pde.core.plugin.IPluginModelBase;
030:        import org.eclipse.pde.internal.core.ibundle.IBundleModel;
031:        import org.eclipse.pde.internal.core.ibundle.IBundlePluginModelBase;
032:        import org.eclipse.pde.internal.core.ibundle.IManifestHeader;
033:        import org.eclipse.pde.internal.core.plugin.ImportObject;
034:        import org.eclipse.pde.internal.core.text.AbstractEditingModel;
035:        import org.eclipse.pde.internal.core.text.IDocumentKey;
036:        import org.eclipse.pde.internal.core.text.IDocumentRange;
037:        import org.eclipse.pde.internal.core.text.IEditingModel;
038:        import org.eclipse.pde.internal.core.text.bundle.Bundle;
039:        import org.eclipse.pde.internal.core.text.bundle.BundleClasspathHeader;
040:        import org.eclipse.pde.internal.core.text.bundle.BundleModel;
041:        import org.eclipse.pde.internal.core.text.bundle.BundleSymbolicNameHeader;
042:        import org.eclipse.pde.internal.core.text.bundle.CompositeManifestHeader;
043:        import org.eclipse.pde.internal.core.text.bundle.ExecutionEnvironment;
044:        import org.eclipse.pde.internal.core.text.bundle.ExportPackageHeader;
045:        import org.eclipse.pde.internal.core.text.bundle.ExportPackageObject;
046:        import org.eclipse.pde.internal.core.text.bundle.ImportPackageHeader;
047:        import org.eclipse.pde.internal.core.text.bundle.ImportPackageObject;
048:        import org.eclipse.pde.internal.core.text.bundle.ManifestHeader;
049:        import org.eclipse.pde.internal.core.text.bundle.PDEManifestElement;
050:        import org.eclipse.pde.internal.core.text.bundle.PackageObject;
051:        import org.eclipse.pde.internal.core.text.bundle.RequireBundleHeader;
052:        import org.eclipse.pde.internal.core.text.bundle.RequireBundleObject;
053:        import org.eclipse.pde.internal.core.text.bundle.RequiredExecutionEnvironmentHeader;
054:        import org.eclipse.pde.internal.ui.PDELabelProvider;
055:        import org.eclipse.pde.internal.ui.PDEPlugin;
056:        import org.eclipse.pde.internal.ui.PDEPluginImages;
057:        import org.eclipse.pde.internal.ui.PDEUIMessages;
058:        import org.eclipse.pde.internal.ui.editor.KeyValueSourcePage;
059:        import org.eclipse.pde.internal.ui.editor.PDEFormEditor;
060:        import org.eclipse.pde.internal.ui.editor.actions.PDEActionConstants;
061:        import org.eclipse.pde.internal.ui.elements.DefaultContentProvider;
062:        import org.eclipse.pde.internal.ui.refactoring.RenamePluginAction;
063:        import org.eclipse.pde.internal.ui.util.SharedLabelProvider;
064:        import org.eclipse.swt.custom.StyledText;
065:        import org.eclipse.swt.graphics.Image;
066:        import org.eclipse.swt.graphics.Point;
067:        import org.eclipse.ui.forms.editor.FormEditor;
068:        import org.osgi.framework.Constants;
069:
070:        public class BundleSourcePage extends KeyValueSourcePage {
071:
072:            /**
073:             * Used to set the selection in the outline view with the link with editor
074:             * feature is enabled
075:             * Cannot use a document range object because manifest header elements
076:             * do not have ranges associated with them in the bundle model
077:             */
078:            private Object fTargetOutlineSelection;
079:
080:            /**
081:             * Offset used to set the current highlight range.
082:             * Used to prevent cyclic event firing when a selection is made in the
083:             * outline view with the link with editor feature on.  When a selection
084:             * is made in the source viewer, an event is fired back to the outline
085:             * view to unnecessarily update the selection.
086:             */
087:            private int fCurrentHighlightRangeOffset;
088:
089:            private final int F_NOT_SET = -1;
090:
091:            private RenamePluginAction fRenameAction;
092:
093:            /**
094:             * BundleOutlineContentProvider
095:             *
096:             */
097:            private class BundleOutlineContentProvider extends
098:                    DefaultContentProvider implements  ITreeContentProvider {
099:
100:                public Object[] getChildren(Object parent) {
101:                    // Need an identifying class for label provider
102:                    if (parent instanceof  ImportPackageHeader) {
103:                        return ((ImportPackageHeader) parent).getPackages();
104:                    } else if (parent instanceof  ExportPackageHeader) {
105:                        return ((ExportPackageHeader) parent).getPackages();
106:                    } else if (parent instanceof  RequiredExecutionEnvironmentHeader) {
107:                        return ((RequiredExecutionEnvironmentHeader) parent)
108:                                .getEnvironments();
109:                    } else if (parent instanceof  RequireBundleHeader) {
110:                        return ((RequireBundleHeader) parent)
111:                                .getRequiredBundles();
112:                    } else if (parent instanceof  BundleClasspathHeader) {
113:                        return getPluginLibraries();
114:                    }
115:                    return new Object[0];
116:                }
117:
118:                private Object[] getPluginLibraries() {
119:                    IPluginLibrary[] libraries = getBundleClasspathLibraries();
120:                    if ((libraries == null) || (libraries.length == 0)) {
121:                        return new Object[0];
122:                    }
123:                    return libraries;
124:                }
125:
126:                public boolean hasChildren(Object parent) {
127:                    return getChildren(parent).length > 0;
128:                }
129:
130:                public Object getParent(Object child) {
131:                    return null;
132:                }
133:
134:                public Object[] getElements(Object parent) {
135:                    if (parent instanceof  BundleModel) {
136:                        BundleModel model = (BundleModel) parent;
137:                        Map manifest = ((Bundle) model.getBundle())
138:                                .getHeaders();
139:                        ArrayList keys = new ArrayList();
140:                        for (Iterator elements = manifest.keySet().iterator(); elements
141:                                .hasNext();) {
142:                            IDocumentKey key = (IDocumentKey) manifest
143:                                    .get(elements.next());
144:                            if (key.getOffset() > -1)
145:                                keys.add(key);
146:                        }
147:                        return keys.toArray();
148:                    }
149:                    return new Object[0];
150:                }
151:            }
152:
153:            /**
154:             * @return
155:             */
156:            private IPluginLibrary[] getBundleClasspathLibraries() {
157:                // The bundle classpath header has no model data members
158:                // Retrieve the plug-in library equivalents from the editor model
159:                FormEditor editor = getEditor();
160:                if (editor instanceof  PDEFormEditor) {
161:                    PDEFormEditor formEditor = (PDEFormEditor) editor;
162:                    IBaseModel baseModel = formEditor.getAggregateModel();
163:                    if (baseModel instanceof  IPluginModelBase) {
164:                        IPluginLibrary[] libraries = ((IPluginModelBase) baseModel)
165:                                .getPluginBase().getLibraries();
166:                        return libraries;
167:                    }
168:                }
169:                return null;
170:            }
171:
172:            private class BundleLabelProvider extends LabelProvider {
173:                // TODO: MP: QO: LOW: Move to PDELabelProvider  
174:                public String getText(Object obj) {
175:                    if (obj instanceof  PackageObject) {
176:                        return ((PackageObject) obj).getName();
177:                    } else if (obj instanceof  ExecutionEnvironment) {
178:                        return ((ExecutionEnvironment) obj).getName();
179:                    } else if (obj instanceof  RequireBundleObject) {
180:                        return getTextRequireBundle(((RequireBundleObject) obj));
181:                    } else if (obj instanceof  ManifestHeader) {
182:                        return ((ManifestHeader) obj).getName();
183:                    }
184:                    return super .getText(obj);
185:                }
186:
187:                private String getTextRequireBundle(RequireBundleObject bundle) {
188:                    StringBuffer label = new StringBuffer();
189:                    // Append the ID
190:                    label.append(bundle.getId());
191:                    // Get the version
192:                    String version = bundle.getVersion();
193:                    // If there is no version, just return what we have
194:                    if ((version == null) || (version.length() == 0)) {
195:                        return label.toString();
196:                    }
197:                    // Append a space
198:                    label.append(' ');
199:                    // If the first character does not have a range indicator,
200:                    // add a default one.  This can happen when there is only one
201:                    // value specified for either min or max
202:                    char firstChar = version.charAt(0);
203:                    if ((firstChar != '(') && (firstChar != '[')) {
204:                        label.append('(');
205:                    }
206:                    // Append the version
207:                    label.append(version);
208:                    // If the last character does not have a range indicator,
209:                    // add a default one.  This can happen when there is only one
210:                    // value specified for either min or max			
211:                    char lastChar = version.charAt(version.length() - 1);
212:                    if ((lastChar != ')') && (lastChar != ']')) {
213:                        label.append(')');
214:                    }
215:                    // Return what we have
216:                    return label.toString();
217:                }
218:
219:                public Image getImage(Object obj) {
220:                    PDELabelProvider labelProvider = PDEPlugin.getDefault()
221:                            .getLabelProvider();
222:                    if (obj instanceof  PackageObject) {
223:                        return labelProvider
224:                                .get(PDEPluginImages.DESC_PACKAGE_OBJ);
225:                    } else if (obj instanceof  ExecutionEnvironment) {
226:                        return labelProvider
227:                                .get(PDEPluginImages.DESC_JAVA_LIB_OBJ);
228:                    } else if (obj instanceof  RequireBundleObject) {
229:                        int flags = SharedLabelProvider.F_EXTERNAL;
230:                        if (((RequireBundleObject) obj).isReexported()) {
231:                            flags = flags | SharedLabelProvider.F_EXPORT;
232:                        }
233:                        return labelProvider.get(
234:                                PDEPluginImages.DESC_REQ_PLUGIN_OBJ, flags);
235:                    } else if (obj instanceof  ManifestHeader) {
236:                        return labelProvider
237:                                .get(PDEPluginImages.DESC_BUILD_VAR_OBJ);
238:                    } else if (obj instanceof  IPluginLibrary) {
239:                        return labelProvider
240:                                .get(PDEPluginImages.DESC_JAVA_LIB_OBJ);
241:                    }
242:                    return null;
243:                }
244:            }
245:
246:            /**
247:             * @param editor
248:             * @param id
249:             * @param title
250:             */
251:            public BundleSourcePage(PDEFormEditor editor, String id,
252:                    String title) {
253:                super (editor, id, title);
254:                resetTargetOutlineSelection();
255:                resetCurrentHighlightRangeOffset();
256:            }
257:
258:            /**
259:             * @param offset
260:             */
261:            private void setCurrentHighlightRangeOffset(int offset) {
262:                fCurrentHighlightRangeOffset = offset;
263:            }
264:
265:            /**
266:             * 
267:             */
268:            private void resetCurrentHighlightRangeOffset() {
269:                fCurrentHighlightRangeOffset = F_NOT_SET;
270:            }
271:
272:            /**
273:             * @return
274:             */
275:            private int getCurrentHighlightRangeOffset() {
276:                return fCurrentHighlightRangeOffset;
277:            }
278:
279:            /* (non-Javadoc)
280:             * @see org.eclipse.ui.texteditor.AbstractTextEditor#resetHighlightRange()
281:             */
282:            public void resetHighlightRange() {
283:                resetCurrentHighlightRangeOffset();
284:                super .resetHighlightRange();
285:            }
286:
287:            /**
288:             * 
289:             */
290:            private void resetTargetOutlineSelection() {
291:                fTargetOutlineSelection = null;
292:            }
293:
294:            /**
295:             * @param object
296:             */
297:            private void setTargetOutlineSelection(Object object) {
298:                fTargetOutlineSelection = object;
299:            }
300:
301:            /**
302:             * @return
303:             */
304:            private Object getTargetOutlineSelection() {
305:                return fTargetOutlineSelection;
306:            }
307:
308:            public ILabelProvider createOutlineLabelProvider() {
309:                return new BundleLabelProvider();
310:            }
311:
312:            public ITreeContentProvider createOutlineContentProvider() {
313:                return new BundleOutlineContentProvider();
314:            }
315:
316:            /* (non-Javadoc)
317:             * @see org.eclipse.pde.internal.ui.editor.PDESourcePage#getRangeElement(int, boolean)
318:             */
319:            public IDocumentRange getRangeElement(int offset,
320:                    boolean searchChildren) {
321:                IBundleModel model = (IBundleModel) getInputContext()
322:                        .getModel();
323:                Map manifest = ((Bundle) model.getBundle()).getHeaders();
324:                // Reset
325:                resetTargetOutlineSelection();
326:                // Search each manifest header
327:                for (Iterator elements = manifest.values().iterator(); elements
328:                        .hasNext();) {
329:                    IDocumentRange node = (IDocumentRange) elements.next();
330:                    // Check to see if the parent is within range
331:                    if (isWithinCurrentRange(offset, node)) {
332:                        // Search the children of composite manifest headers first if
333:                        // specified
334:                        if (searchChildren
335:                                && (node instanceof  CompositeManifestHeader)) {
336:                            IDocumentRange child_node = getRangeElementChild(
337:                                    model, offset,
338:                                    (CompositeManifestHeader) node);
339:                            // If the child node is specified return it; otherwise, we 
340:                            // will default to the parent node
341:                            if (child_node != null) {
342:                                return child_node;
343:                            }
344:                        }
345:                        // A manifest header object can be used both for setting the
346:                        // highlight range and making a selection in the outline view
347:                        setTargetOutlineSelection(node);
348:                        return node;
349:                    }
350:                }
351:                return null;
352:            }
353:
354:            /**
355:             * @param offset
356:             * @param range
357:             * @return true if the offset is within the range; false, otherwise
358:             */
359:            private boolean isWithinCurrentRange(int offset,
360:                    IDocumentRange range) {
361:
362:                if (range == null) {
363:                    // Range not set
364:                    return false;
365:                } else if (offset >= range.getOffset()
366:                        && (offset <= (range.getOffset() + range.getLength()))) {
367:                    // Offset within range
368:                    return true;
369:                }
370:                // Offset not within range
371:                return false;
372:            }
373:
374:            /**
375:             * This method is required because the calculated ranges, do NOT include
376:             * their parameters (e.g. x-friends, bundle-version)
377:             * @param offset
378:             * @param current_range
379:             * @param previous_range
380:             * @return true if the offset falls in between the end of the previous range
381:             * and before the current range (e.g. the previous ranges parameters)
382:             */
383:            private boolean isWithinPreviousRange(int offset,
384:                    IDocumentRange current_range, IDocumentRange previous_range) {
385:
386:                if ((current_range == null) || (previous_range == null)) {
387:                    // Range not set
388:                    return false;
389:                } else if ((offset >= previous_range.getOffset()
390:                        + previous_range.getLength())
391:                        && ((offset <= current_range.getOffset()))) {
392:                    // Offset within range
393:                    return true;
394:                }
395:                // Offset not within range
396:                return false;
397:            }
398:
399:            /**
400:             * @param offset
401:             * @param previousRange
402:             * @return
403:             */
404:            private boolean isBeforePreviousRange(int offset,
405:                    IDocumentRange previousRange) {
406:
407:                if (previousRange == null) {
408:                    return false;
409:                } else if (offset < previousRange.getOffset()) {
410:                    return true;
411:                }
412:                return false;
413:            }
414:
415:            /**
416:             * @param model
417:             * @param offset
418:             * @param header
419:             * @return
420:             */
421:            private IDocumentRange getRangeElementChild(IBundleModel model,
422:                    int offset, CompositeManifestHeader header) {
423:                // Ensure the header has associated elements
424:                if (header.isEmpty()) {
425:                    return null;
426:                }
427:                // Get the header elements
428:                PDEManifestElement[] elements = header.getElements();
429:                // Get the header elements name (assume that all elements are the same
430:                // as the first element)
431:                String headerName = getHeaderName(elements[0]);
432:                PDEManifestElement previousElement = null;
433:                PDEManifestElement currentElement = null;
434:                IDocumentRange previousRange = null;
435:                IDocumentRange currentRange = null;
436:                // Process each element
437:                for (int i = 0; i < elements.length; i++) {
438:                    currentElement = elements[i];
439:                    // Find the range for the element
440:                    currentRange = getSpecificRange(model, headerName,
441:                            currentElement.getValue());
442:                    // Determine whether the element is within range
443:                    if (isBeforePreviousRange(offset, previousRange)) {
444:                        return null;
445:                    } else if (isWithinCurrentRange(offset, currentRange)) {
446:                        setChildTargetOutlineSelection(headerName,
447:                                currentElement);
448:                        // Use for setting the highlight range
449:                        return currentRange;
450:                    } else if (isWithinPreviousRange(offset, currentRange,
451:                            previousRange)) {
452:                        setChildTargetOutlineSelection(headerName,
453:                                previousElement);
454:                        // Use for setting the highlight range
455:                        return previousRange;
456:                    }
457:                    // Update for the next iteration
458:                    previousRange = currentRange;
459:                    previousElement = currentElement;
460:                }
461:
462:                if (isWithinLastElementParamRange(offset, currentRange, header)) {
463:                    // No element found within range
464:                    setChildTargetOutlineSelection(headerName, currentElement);
465:                    // Use for setting the highlight range
466:                    return currentRange;
467:                }
468:                return null;
469:            }
470:
471:            /**
472:             * @param offset
473:             * @param currentRange
474:             * @param headerRange
475:             * @return
476:             */
477:            private boolean isWithinLastElementParamRange(int offset,
478:                    IDocumentRange currentRange, IDocumentRange headerRange) {
479:                if (currentRange == null) {
480:                    return false;
481:                } else if ((offset >= currentRange.getOffset()
482:                        + currentRange.getLength())
483:                        && (offset <= (headerRange.getOffset() + headerRange
484:                                .getLength()))) {
485:                    return true;
486:                }
487:                return false;
488:            }
489:
490:            /**
491:             * @param headerName
492:             * @param element
493:             */
494:            private void setChildTargetOutlineSelection(String headerName,
495:                    PDEManifestElement element) {
496:                // Use for setting the outline view selection
497:                if (headerName.equalsIgnoreCase(Constants.BUNDLE_CLASSPATH)) {
498:                    setTargetOutlineSelection(getBundleClasspathOutlineSelection(element));
499:                } else {
500:                    setTargetOutlineSelection(element);
501:                }
502:            }
503:
504:            /**
505:             * Edge Case:  Cannot use the PDEManifestElement directly to select bundle
506:             * classpath elements in the outline view.  Need to use IPluginLibrary
507:             * objects
508:             * @param manifestElement
509:             * @return
510:             */
511:            private Object getBundleClasspathOutlineSelection(
512:                    PDEManifestElement manifestElement) {
513:
514:                IPluginLibrary[] libraries = getBundleClasspathLibraries();
515:                // Ensure there are libraries
516:                if ((libraries == null) || (libraries.length == 0)) {
517:                    return null;
518:                }
519:                // Linearly search for the equivalent library object
520:                for (int i = 0; i < libraries.length; i++) {
521:                    if (manifestElement.getValue().equals(
522:                            libraries[i].getName())) {
523:                        // Found
524:                        return libraries[i];
525:                    }
526:                }
527:                // None found
528:                return null;
529:            }
530:
531:            /**
532:             * @param element
533:             * @return
534:             */
535:            private String getHeaderName(PDEManifestElement element) {
536:                if (element instanceof  ExportPackageObject) {
537:                    return Constants.EXPORT_PACKAGE;
538:                } else if (element instanceof  ImportPackageObject) {
539:                    return Constants.IMPORT_PACKAGE;
540:                } else if (element instanceof  ExecutionEnvironment) {
541:                    return Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT;
542:                } else if (element instanceof  RequireBundleObject) {
543:                    return Constants.REQUIRE_BUNDLE;
544:                } else {
545:                    // Bundle classpath elements do not have their own model class
546:                    // They are created as PDEManifestElements directly whose value
547:                    // is just a String
548:                    // Assume that if the element is none of the above types it is this
549:                    // type
550:                    return Constants.BUNDLE_CLASSPATH;
551:                }
552:            }
553:
554:            protected String[] collectContextMenuPreferencePages() {
555:                String[] ids = super .collectContextMenuPreferencePages();
556:                String[] more = new String[ids.length + 1];
557:                more[0] = "org.eclipse.pde.ui.EditorPreferencePage"; //$NON-NLS-1$
558:                System.arraycopy(ids, 0, more, 1, ids.length);
559:                return more;
560:            }
561:
562:            public IDocumentRange findRange() {
563:                if (fSelection instanceof  ImportObject) {
564:                    IPluginModelBase base = ((ImportObject) fSelection)
565:                            .getImport().getPluginModel();
566:                    if (base instanceof  IBundlePluginModelBase)
567:                        return getSpecificRange(((IBundlePluginModelBase) base)
568:                                .getBundleModel(), Constants.REQUIRE_BUNDLE,
569:                                ((ImportObject) fSelection).getId());
570:                } else if (fSelection instanceof  ImportPackageObject) {
571:                    return getSpecificRange(((ImportPackageObject) fSelection)
572:                            .getModel(), Constants.IMPORT_PACKAGE,
573:                            ((ImportPackageObject) fSelection).getValue());
574:                } else if (fSelection instanceof  ExportPackageObject) {
575:                    return getSpecificRange(((ExportPackageObject) fSelection)
576:                            .getModel(), Constants.EXPORT_PACKAGE,
577:                            ((ExportPackageObject) fSelection).getValue());
578:                } else if (fSelection instanceof  IPluginLibrary) {
579:                    IPluginModelBase base = ((IPluginLibrary) fSelection)
580:                            .getPluginModel();
581:                    if (base instanceof  IBundlePluginModelBase)
582:                        return getSpecificRange(((IBundlePluginModelBase) base)
583:                                .getBundleModel(), Constants.BUNDLE_CLASSPATH,
584:                                ((IPluginLibrary) fSelection).getName());
585:                } else if (fSelection instanceof  ExecutionEnvironment) {
586:                    return getSpecificRange(((ExecutionEnvironment) fSelection)
587:                            .getModel(),
588:                            Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT,
589:                            ((ExecutionEnvironment) fSelection).getValue());
590:                } else if (fSelection instanceof  RequireBundleObject) {
591:                    return getSpecificRange(((RequireBundleObject) fSelection)
592:                            .getModel(), Constants.REQUIRE_BUNDLE,
593:                            ((RequireBundleObject) fSelection).getId());
594:                }
595:                return null;
596:            }
597:
598:            public static IDocumentRange getSpecificRange(IBundleModel model,
599:                    IManifestHeader header, String element) {
600:                if (header == null || !(model instanceof  IEditingModel))
601:                    return null;
602:
603:                final int[] range = new int[] { -1, -1 }; // { offset, length }
604:                try {
605:                    int start = header.getOffset() + header.getName().length();
606:                    int length = header.getLength() - header.getName().length();
607:                    String headerValue = ((IEditingModel) model).getDocument()
608:                            .get(start, length);
609:
610:                    int i = headerValue.indexOf(element);
611:                    int last = headerValue.lastIndexOf(element);
612:                    if (i > 0 && i != last) {
613:                        char[] sChar = element.toCharArray();
614:                        char[] headerChar = headerValue.toCharArray();
615:                        headLoop: for (; i <= last; i++) {
616:                            // check 1st, middle and last chars to speed things up
617:                            if (headerChar[i] != sChar[0]
618:                                    && headerChar[i + sChar.length / 2] != sChar[sChar.length / 2]
619:                                    && headerChar[i + sChar.length - 1] != sChar[sChar.length - 1])
620:                                continue headLoop;
621:
622:                            for (int j = 1; j < sChar.length - 1; j++)
623:                                if (headerChar[i + j] != sChar[j])
624:                                    continue headLoop;
625:
626:                            // found match
627:                            char c = headerChar[i - 1];
628:                            if (!Character.isWhitespace(c) && c != ',')
629:                                // search string is contained by another
630:                                continue headLoop;
631:
632:                            int index = i + sChar.length;
633:                            if (index >= headerChar.length) {
634:                                // Current match is longer than search
635:                                // Occurs when match is '.' or a single character
636:                                continue;
637:                            }
638:                            c = headerChar[index];
639:                            if ((c >= 'a' && c <= 'z')
640:                                    || (c >= 'A' && c <= 'Z') || c == '.')
641:                                // current match is longer than search
642:                                continue headLoop;
643:
644:                            break;
645:                        }
646:                    }
647:                    if (i != -1) {
648:                        range[0] = start + i;
649:                        range[1] = element.length();
650:                    }
651:                } catch (BadLocationException e) {
652:                }
653:                if (range[0] == -1) { // if un-set offset use header range
654:                    range[0] = header.getOffset();
655:                    // Only select the length of the header name; otherwise, the 
656:                    // header value will be included in the selection
657:                    range[1] = header.getName().length();
658:                }
659:                return new IDocumentRange() {
660:                    public int getOffset() {
661:                        return range[0];
662:                    }
663:
664:                    public int getLength() {
665:                        return range[1];
666:                    }
667:                };
668:            }
669:
670:            public static IDocumentRange getSpecificRange(IBundleModel model,
671:                    String headerName, String search) {
672:                IManifestHeader header = model.getBundle().getManifestHeader(
673:                        headerName);
674:                return getSpecificRange(model, header, search);
675:            }
676:
677:            protected boolean isSelectionListener() {
678:                return true;
679:            }
680:
681:            public Object getAdapter(Class adapter) {
682:                if (IHyperlinkDetector.class.equals(adapter))
683:                    return new BundleHyperlinkDetector(this );
684:                return super .getAdapter(adapter);
685:            }
686:
687:            /* (non-Javadoc)
688:             * @see org.eclipse.pde.internal.ui.editor.PDESourcePage#updateSelection(java.lang.Object)
689:             */
690:            public void updateSelection(Object object) {
691:                // Update the global selection
692:                fSelection = object;
693:                // Highlight the selection if it is a manifest header
694:                if (object instanceof  IDocumentKey) {
695:                    setHighlightRange((IDocumentKey) object);
696:                    setCurrentHighlightRangeOffset(((IDocumentKey) object)
697:                            .getOffset());
698:                    // We don't set the selected range because it will cause the 
699:                    // manifest header and all its value to be selected
700:                    return;
701:                }
702:                // Handle manifest header values
703:                // Determine the selection range
704:                IDocumentRange range = findRange();
705:                // Ensure there is a range
706:                if (range == null) {
707:                    return;
708:                }
709:                // Get the model
710:                IBaseModel model = getInputContext().getModel();
711:                // Ensure we have an editing model
712:                if ((model instanceof  AbstractEditingModel) == false) {
713:                    return;
714:                }
715:                // If the range offset is undefined or the source viewer is dirty,
716:                // forcibly adjust the offsets and try to find the range again
717:                if ((range.getOffset() == -1) || isDirty()) {
718:                    try {
719:                        ((AbstractEditingModel) model)
720:                                .adjustOffsets(((AbstractEditingModel) model)
721:                                        .getDocument());
722:                    } catch (CoreException e) {
723:                        // Ignore
724:                    }
725:                    range = findRange();
726:                }
727:                // Set the highlight and selected range with whatever we found
728:                setCurrentHighlightRangeOffset(range.getOffset());
729:                setHighlightRange(range, true);
730:                setSelectedRange(range, false);
731:            }
732:
733:            /* (non-Javadoc)
734:             * @see org.eclipse.pde.internal.ui.editor.PDESourcePage#handleSelectionChangedSourcePage(org.eclipse.jface.viewers.SelectionChangedEvent)
735:             */
736:            protected void handleSelectionChangedSourcePage(
737:                    SelectionChangedEvent event) {
738:                ISelection selection = event.getSelection();
739:                // Ensure we have a selection
740:                if (selection.isEmpty()
741:                        || ((selection instanceof  ITextSelection) == false)) {
742:                    return;
743:                }
744:                // If the page has been edited, adjust the offsets; otherwise, our
745:                // caculated ranges will be out of sync
746:                IBaseModel model = getInputContext().getModel();
747:                if (model instanceof  AbstractEditingModel && isDirty()) {
748:                    try {
749:                        ((AbstractEditingModel) model)
750:                                .adjustOffsets(((AbstractEditingModel) model)
751:                                        .getDocument());
752:                    } catch (CoreException e) {
753:                        // Ignore
754:                    }
755:                }
756:                // Synchronize using the current cursor position in this page
757:                synchronizeOutlinePage(((ITextSelection) selection).getOffset());
758:            }
759:
760:            /* (non-Javadoc)
761:             * @see org.eclipse.pde.internal.ui.editor.PDESourcePage#synchronizeOutlinePage(int)
762:             */
763:            protected void synchronizeOutlinePage(int offset) {
764:                // Prevent cyclical firing of events between source page and outline
765:                // view
766:                // If the previous offset is the same as the current offset, then 
767:                // the selection does not need to be updated in the outline view
768:                int previous_offset = getCurrentHighlightRangeOffset();
769:                if (previous_offset == offset) {
770:                    return;
771:                }
772:                // Find the range header (parent) or element (children) within range of 
773:                // the text selection offset
774:                IDocumentRange rangeElement = getRangeElement(offset, true);
775:                // Set the highlight range 
776:                updateHighlightRange(rangeElement);
777:                // Set the outline view selection
778:                updateOutlinePageSelection(getTargetOutlineSelection());
779:            }
780:
781:            protected void editorContextMenuAboutToShow(IMenuManager menu) {
782:                super .editorContextMenuAboutToShow(menu);
783:                StyledText text = getViewer().getTextWidget();
784:                Point p = text.getSelection();
785:                IDocumentRange element = getRangeElement(p.x, false);
786:                // only activate rename when user is highlighting Bundle-SymbolicName header
787:                if (!(element instanceof  BundleSymbolicNameHeader)
788:                        || !(((BundleSymbolicNameHeader) element).getModel()
789:                                .isEditable()))
790:                    return;
791:                if (fRenameAction == null) {
792:                    IBaseModel base = ((PDEFormEditor) getEditor())
793:                            .getAggregateModel();
794:                    if (base instanceof  IPluginModelBase) {
795:                        fRenameAction = new RenamePluginAction();
796:                        fRenameAction
797:                                .setText(NLS
798:                                        .bind(
799:                                                PDEUIMessages.BundleSourcePage_renameActionText,
800:                                                Constants.BUNDLE_SYMBOLICNAME));
801:                        fRenameAction.setPlugin((IPluginModelBase) base);
802:                    }
803:                }
804:                if (fRenameAction != null)
805:                    // add rename action after Outline. This is the same order as the hyperlink actions
806:                    menu.insertAfter(
807:                            PDEActionConstants.COMMAND_ID_QUICK_OUTLINE,
808:                            fRenameAction);
809:            }
810:
811:            /* (non-Javadoc)
812:             * @see org.eclipse.pde.internal.ui.editor.PDESourcePage#setActive(boolean)
813:             */
814:            public void setActive(boolean active) {
815:                super .setActive(active);
816:                // Update the text selection if this page is being activated
817:                if (active) {
818:                    updateTextSelection();
819:                }
820:            }
821:
822:        }
ww__w.___ja_va___2_s_.___c_om___ | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.