KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ant > internal > ui > editor > text > AntFoldingStructureProvider


1 /*******************************************************************************
2  * Copyright (c) 2004, 2005 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.ant.internal.ui.editor.text;
13
14 import java.util.ArrayList JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import java.util.HashSet JavaDoc;
17 import java.util.Iterator JavaDoc;
18 import java.util.List JavaDoc;
19 import java.util.Map JavaDoc;
20 import java.util.Set JavaDoc;
21
22 import org.eclipse.ant.internal.ui.editor.AntEditor;
23 import org.eclipse.ant.internal.ui.model.AntElementNode;
24 import org.eclipse.ant.internal.ui.model.AntModel;
25 import org.eclipse.ant.internal.ui.model.AntProjectNode;
26 import org.eclipse.jface.text.BadLocationException;
27 import org.eclipse.jface.text.IDocument;
28 import org.eclipse.jface.text.Position;
29 import org.eclipse.jface.text.source.Annotation;
30 import org.eclipse.jface.text.source.projection.ProjectionAnnotation;
31 import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel;
32
33 public class AntFoldingStructureProvider {
34     
35     private AntEditor fEditor;
36     private IDocument fDocument;
37     
38     /**
39      * A mapping of the foldable position to the <code>AntElementNode<code> that represent that region
40      */

41     private Map JavaDoc fPositionToElement= new HashMap JavaDoc();
42     
43     public AntFoldingStructureProvider(AntEditor editor) {
44         super();
45         fEditor = editor;
46     }
47     
48     private void updateFoldingRegions(ProjectionAnnotationModel model, Set JavaDoc currentRegions) {
49         Annotation[] deletions = computeDifferences(model, currentRegions);
50
51         Map JavaDoc additionsMap = new HashMap JavaDoc();
52         for (Iterator JavaDoc iter = currentRegions.iterator(); iter.hasNext();) {
53             Object JavaDoc position= iter.next();
54             AntElementNode node= (AntElementNode)fPositionToElement.get(position);
55             additionsMap.put(new ProjectionAnnotation(node.collapseProjection()), position);
56         }
57
58         if ((deletions.length != 0 || additionsMap.size() != 0)) {
59             model.modifyAnnotations(deletions, additionsMap, new Annotation[] {});
60         }
61     }
62
63     private Annotation[] computeDifferences(ProjectionAnnotationModel model, Set JavaDoc additions) {
64         List JavaDoc deletions = new ArrayList JavaDoc();
65         for (Iterator JavaDoc iter = model.getAnnotationIterator(); iter.hasNext();) {
66             Object JavaDoc annotation = iter.next();
67             if (annotation instanceof ProjectionAnnotation) {
68                 Position position = model.getPosition((Annotation) annotation);
69                 if (additions.contains(position)) {
70                     additions.remove(position);
71                 } else {
72                     deletions.add(annotation);
73                 }
74             }
75         }
76         return (Annotation[]) deletions.toArray(new Annotation[deletions.size()]);
77     }
78
79     public void updateFoldingRegions(AntModel antModel) {
80         fPositionToElement= new HashMap JavaDoc();
81         try {
82             ProjectionAnnotationModel model = (ProjectionAnnotationModel) fEditor.getAdapter(ProjectionAnnotationModel.class);
83             if (model == null) {
84                 return;
85             }
86     
87             Set JavaDoc currentRegions= new HashSet JavaDoc();
88             AntProjectNode node= antModel.getProjectNode();
89             if (node == null || node.getOffset() == -1 || node.getLength() == -1) {
90                 return;
91             }
92             List JavaDoc root= new ArrayList JavaDoc(2);
93             root.add(node);
94             List JavaDoc nodes= antModel.getNonStructuralNodes();
95             root.addAll(nodes);
96             addFoldingRegions(currentRegions, root);
97             updateFoldingRegions(model, currentRegions);
98         } catch (BadLocationException be) {
99             //ignore as document has changed
100
}
101     }
102     
103     private void addFoldingRegions(Set JavaDoc regions, List JavaDoc children) throws BadLocationException {
104         // add a Position to 'regions' for each foldable region
105
Iterator JavaDoc iter= children.iterator();
106         while (iter.hasNext()) {
107             AntElementNode element = (AntElementNode) iter.next();
108             if (element.getImportNode() != null || element.isExternal()) {
109                 continue; //elements are not really in this document and therefore are not foldable
110
}
111             int startLine= fDocument.getLineOfOffset(element.getOffset());
112             int endLine= fDocument.getLineOfOffset(element.getOffset() + element.getLength());
113             if (startLine < endLine) {
114                 int start= fDocument.getLineOffset(startLine);
115                 int end= fDocument.getLineOffset(endLine) + fDocument.getLineLength(endLine);
116                 Position position= new Position(start, end - start);
117                 regions.add(position);
118                 fPositionToElement.put(position, element);
119             }
120             
121             children= element.getChildNodes();
122             if (children != null) {
123                 addFoldingRegions(regions, children);
124             }
125         }
126     }
127
128     public void setDocument(IDocument document) {
129         fDocument= document;
130     }
131 }
132
Popular Tags