KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ant > internal > ui > editor > model > AntElementNode


1 /*******************************************************************************
2  * Copyright (c) 2002, 2004 GEBIT Gesellschaft fuer EDV-Beratung
3  * und Informatik-Technologien mbH,
4  * Berlin, Duesseldorf, Frankfurt (Germany) and others.
5  * All rights reserved. This program and the accompanying materials
6  * are made available under the terms of the Common Public License v1.0
7  * which accompanies this distribution, and is available at
8  * http://www.eclipse.org/legal/cpl-v10.html
9  *
10  * Contributors:
11  * GEBIT Gesellschaft fuer EDV-Beratung und Informatik-Technologien mbH - initial API and implementation
12  * IBM Corporation - bug fixes
13  * John-Mason P. Shackelford (john-mason.shackelford@pearson.com) - bug 49445
14  *******************************************************************************/

15
16 package org.eclipse.ant.internal.ui.editor.model;
17
18 import java.io.File JavaDoc;
19 import java.net.MalformedURLException JavaDoc;
20 import java.net.URL JavaDoc;
21 import java.text.MessageFormat JavaDoc;
22 import java.util.ArrayList JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.List JavaDoc;
25
26 import org.eclipse.ant.internal.ui.editor.outline.AntModel;
27 import org.eclipse.ant.internal.ui.editor.outline.IProblem;
28 import org.eclipse.ant.internal.ui.editor.outline.LocationProvider;
29 import org.eclipse.ant.internal.ui.editor.outline.XMLProblem;
30 import org.eclipse.ant.internal.ui.model.AntImageDescriptor;
31 import org.eclipse.ant.internal.ui.model.AntUIImages;
32 import org.eclipse.ant.internal.ui.model.AntUtil;
33 import org.eclipse.ant.internal.ui.model.IAntUIConstants;
34 import org.eclipse.core.resources.IFile;
35 import org.eclipse.core.runtime.IAdaptable;
36 import org.eclipse.core.runtime.Path;
37 import org.eclipse.core.runtime.Platform;
38 import org.eclipse.jface.resource.ImageDescriptor;
39 import org.eclipse.swt.graphics.Image;
40
41 /**
42  * General representation of an Ant buildfile element.
43  *
44  */

45 public class AntElementNode implements IAdaptable {
46     
47     /**
48      * The offset of the corresponding source.
49      * @see #getOffset()
50      */

51     protected int offset= -1;
52     
53     /**
54      * The length of the corresponding source.
55      * @see #getLength()
56      */

57     protected int length= -1;
58     
59     /**
60      * The length of the source to select for this node
61      */

62     protected int selectionLength;
63     
64     /**
65      * The parent node.
66      */

67     protected AntElementNode parent;
68     
69     /**
70      * The import node that "imported" this element
71      */

72     private AntElementNode importNode;
73
74     /**
75      * The child nodes.
76      */

77     protected List JavaDoc childNodes= null;
78
79     /**
80      * The (tag-)name of the element.
81      */

82     protected String JavaDoc name;
83
84     /**
85      * Whether this element has been generated as part of an element hierarchy
86      * this has problems. This is the severity of the problem.
87      * @see XMLProblem#NO_PROBLEM
88      * @see XMLProblem#SEVERITY_ERROR
89      * @see XMLProblem#SEVERITY_WARNING
90      * @see XMLProblem#SEVERITY_FATAL_ERROR
91      */

92     private int problemSeverity= XMLProblem.NO_PROBLEM;
93     
94     /**
95      * The absolute file system path of the file this element is
96      * defined within.
97      */

98     private String JavaDoc filePath;
99     
100     /**
101      * Whether this element has been generated from an external entity definition
102      */

103     private boolean isExternal = false;
104     
105     /**
106      * The unique (in the corresponding element tree) path of this element.
107      */

108     private String JavaDoc fElementPath;
109     
110     /**
111      * The (not necessarily unique) identifier of this element.
112      */

113     private String JavaDoc fElementIdentifier;
114
115     /**
116      * The problem associated with this node. May be <code>null</code>.
117      */

118     private IProblem fProblem;
119     
120     /**
121      * Only used when opening an import element to indicate the location in the imported file
122      */

123     private int fLine;
124     private int fColumn;
125
126     /**
127      * Creates an instance with the specified name.
128      */

129     public AntElementNode(String JavaDoc aName) {
130        name = aName;
131     }
132     
133     /**
134      * Creates an instance with the specified name.
135      */

136     public AntElementNode() {
137     }
138     
139     
140     /**
141      * Returns the name.
142      */

143     public String JavaDoc getName() {
144         return name;
145     }
146     
147     
148     /**
149      * Returns the label that is used for display in outline view.
150      * <P>
151      * The default implementation returns just the same as the method <code>getName()</code>.
152      * Override this method in your own subclass for special elements in order to provide a
153      * custom label.
154      */

155     public String JavaDoc getLabel() {
156         return getName();
157     }
158     
159     
160     /**
161      * Returns the child nodes.
162      */

163     public List JavaDoc getChildNodes() {
164         return childNodes;
165     }
166     
167     /**
168      * Returns all the descendents of this target
169      */

170     public List JavaDoc getDescendents() {
171         if (childNodes == null) {
172             return null;
173         }
174         List JavaDoc descendents= new ArrayList JavaDoc();
175         determineDescendents(descendents, childNodes);
176         
177         return descendents;
178     }
179     
180     
181     private void determineDescendents(List JavaDoc descendents, List JavaDoc childrenNodes) {
182         Iterator JavaDoc itr= childrenNodes.iterator();
183         while (itr.hasNext()) {
184             AntElementNode element = (AntElementNode) itr.next();
185             if (element.hasChildren()) {
186                 determineDescendents(descendents, element.getChildNodes());
187             }
188             descendents.add(element);
189         }
190     }
191
192     /**
193      * Returns the parent <code>AntElementNode</code>.
194      *
195      * @return the parent or <code>null</code> if this element has no parent.
196      */

197     public AntElementNode getParentNode() {
198         return parent;
199     }
200     
201     public AntProjectNode getProjectNode() {
202         AntElementNode projectParent= getParentNode();
203         while (projectParent != null && !(projectParent instanceof AntProjectNode)) {
204             projectParent= projectParent.getParentNode();
205         }
206         return (AntProjectNode)projectParent;
207     }
208     
209     
210     /**
211      * Adds the specified element as child.
212      * <P>
213      * The specified element will have this assigned as its parent.
214      *
215      */

216     public void addChildNode(AntElementNode childElement) {
217         childElement.setParent(this);
218         if (childNodes == null) {
219             childNodes= new ArrayList JavaDoc();
220         }
221         childNodes.add(childElement);
222     }
223     
224     protected void setParent(AntElementNode node) {
225         parent= node;
226     }
227
228     /**
229      * Sets the absolute file system path of the file this element is defined
230      * within.
231      */

232     public void setFilePath(String JavaDoc path) {
233         if (path == null) {
234             return;
235         }
236         URL JavaDoc url= null;
237         try {
238             url= new URL JavaDoc(path);
239         } catch (MalformedURLException JavaDoc e) {
240             filePath= path;
241             return;
242         }
243         filePath = new Path(new File JavaDoc(url.getPath()).getAbsolutePath()).toString();
244     }
245     
246     /**
247      * Returns the absolute file system path of the file this element is defined
248      * within. Only relevant for nodes that are external
249      * @see #isExternal()
250      */

251     public String JavaDoc getFilePath() {
252         return filePath;
253     }
254
255     /**
256      * Returns the 0-based index of the first character of the source code for this element,
257      * relative to the source buffer in which this element is contained.
258      *
259      * @return the 0-based index of the first character of the source code for this element,
260      * relative to the source buffer in which this element is contained
261      */

262     public int getOffset() {
263         return offset;
264     }
265     
266     /**
267      * Sets the offset.
268      *
269      * @see #getOffset()
270      */

271     public void setOffset(int anOffset) {
272         offset = anOffset;
273     }
274     
275     /**
276      * Returns the number of characters of the source code for this element,
277      * relative to the source buffer in which this element is contained.
278      *
279      * @return the number of characters of the source code for this element,
280      * relative to the source buffer in which this element is contained
281      */

282     public int getLength() {
283         return length;
284     }
285
286     /**
287      * Sets the length.
288      *
289      * @see #getLength()
290      */

291     public void setLength(int aLength) {
292         length = aLength;
293         if (fProblem != null && fProblem instanceof XMLProblem) {
294             ((XMLProblem)fProblem).setLength(aLength);
295             fProblem= null;
296         }
297     }
298
299     /**
300      * Returns a string representation of this element.
301      */

302     public String JavaDoc toString() {
303         return "Ant Element Node: " + getLabel() + " Offset: " + getOffset() + " Length: " + getLength(); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
304
}
305     
306     /**
307      * Returns whether this element has been generated as part of an element
308      * hierarchy this is not complete as a result of an error.
309      */

310     public boolean isErrorNode() {
311         return problemSeverity == XMLProblem.SEVERITY_ERROR || problemSeverity == XMLProblem.SEVERITY_FATAL_ERROR;
312     }
313     
314     /**
315      * Returns whether this element has been generated as part of an element
316      * hierarchy that has warning(s) associated with it
317      */

318     public boolean isWarningNode() {
319         return problemSeverity == XMLProblem.SEVERITY_WARNING;
320     }
321     
322     /**
323      * Sets whether this element has been generated as part of an element
324      * hierarchy that has problems. The severity of the problem is provided.
325      */

326     public void setProblemSeverity(int severity) {
327         this.problemSeverity= severity;
328     }
329     
330     /**
331      * Returns whether this xml element is defined in an external entity.
332      *
333      * @return boolean
334      */

335     public boolean isExternal() {
336         return isExternal;
337     }
338
339     /**
340      * Sets whether this xml element is defined in an external entity.
341      */

342     public void setExternal(boolean isExternal) {
343         this.isExternal = isExternal;
344     }
345     
346     private String JavaDoc getElementPath() {
347         if (fElementPath == null) {
348             StringBuffer JavaDoc buffer= new StringBuffer JavaDoc(getParentNode() != null ? getParentNode().getElementPath() : ""); //$NON-NLS-1$
349
buffer.append('/');
350             buffer.append(getElementIdentifier());
351             buffer.append('[');
352             buffer.append(getParentNode() != null ? getParentNode().getElementIndexOf(this) : 0);
353             buffer.append(']');
354             
355             fElementPath= buffer.toString();
356         }
357         return fElementPath;
358     }
359
360     private String JavaDoc getElementIdentifier() {
361         if (fElementIdentifier == null) {
362             StringBuffer JavaDoc buffer= escape(new StringBuffer JavaDoc(getName() != null ? getName() : ""), '\\', "$/[]\\"); //$NON-NLS-1$ //$NON-NLS-2$
363
buffer.append('$');
364             buffer.append(escape(new StringBuffer JavaDoc(getLabel() != null ? getLabel() : ""), '\\', "$/[]\\").toString()); //$NON-NLS-1$ //$NON-NLS-2$
365

366             fElementIdentifier= buffer.toString();
367         }
368         return fElementIdentifier;
369     }
370
371     private StringBuffer JavaDoc escape(StringBuffer JavaDoc sb, char esc, String JavaDoc special) {
372         for (int i= 0; i < sb.length(); i++) {
373             if (special.indexOf(sb.charAt(i)) >= 0) {
374                 sb.insert(i++, esc);
375             }
376         }
377
378         return sb;
379     }
380
381     private int getElementIndexOf(AntElementNode child) {
382         if (getChildNodes() == null) {
383             return -1;
384         }
385         
386         int result= -1;
387         
388         Iterator JavaDoc iter= getChildNodes().iterator();
389         AntElementNode current= null;
390         while (current != child && iter.hasNext()) {
391             current= (AntElementNode) iter.next();
392             if (child.getElementIdentifier().equals(current.getElementIdentifier()))
393                 result++;
394         }
395         
396         if (current != child) {
397             return -1;
398         }
399         
400         return result;
401     }
402
403     /*
404      * @see java.lang.Object#equals(java.lang.Object)
405      */

406     public boolean equals(Object JavaDoc o2) {
407         // prepared to be used in an IElementComparer, depends on http://dev.eclipse.org/bugs/show_bug.cgi?id=32254
408
Object JavaDoc o1= this;
409         
410         if (o1 == o2) {
411             return true;
412         }
413         if (o1 == null || o2 == null) {
414             return false;
415         }
416         if (!(o1 instanceof AntElementNode || o2 instanceof AntElementNode)) {
417             return o2.equals(o1);
418         }
419         if (!(o1 instanceof AntElementNode && o2 instanceof AntElementNode)) {
420             return false;
421         }
422         
423         AntElementNode e1= (AntElementNode) o1;
424         AntElementNode e2= (AntElementNode) o2;
425     
426         return e1.getElementPath().equals(e2.getElementPath());
427     }
428
429     /*
430      * @see java.lang.Object#hashCode()
431      */

432     public int hashCode() {
433         // prepared to be used in an IElementComparer, depends on http://dev.eclipse.org/bugs/show_bug.cgi?id=32254
434

435         return getElementPath().hashCode();
436     }
437
438     /**
439      * Returns the length of source to select for this node.
440      * @return the length of source to select
441      */

442     public int getSelectionLength() {
443         return selectionLength;
444     }
445     
446     public void setSelectionLength(int selectionLength) {
447         this.selectionLength= selectionLength;
448     }
449     
450     /**
451      * Returns the node with the narrowest source range that contains the offset.
452      * It may be this node or one of its children or <code>null</code> if the offset is not in the source range of this node.
453      * @param sourceOffset The source offset
454      * @return the node that includes the offset in its source range or <code>null</code>
455      */

456     public AntElementNode getNode(int sourceOffset) {
457         if (childNodes != null) {
458             for (Iterator JavaDoc iter = childNodes.iterator(); iter.hasNext(); ) {
459                 AntElementNode node = (AntElementNode) iter.next();
460                 AntElementNode containingNode= node.getNode(sourceOffset);
461                 if (containingNode != null) {
462                     return containingNode;
463                 }
464             }
465         }
466         if (length == -1 && offset <= sourceOffset && !isExternal()) { //this is still an open element
467
return this;
468         }
469         if (offset <= sourceOffset && sourceOffset <= (offset + length - 2)) {
470             return this;
471         }
472         
473         return null;
474     }
475     
476     public Image getImage() {
477         int flags = 0;
478         
479         if (isErrorNode()) {
480             flags = flags | AntImageDescriptor.HAS_ERRORS;
481         } else if (isWarningNode()) {
482             flags = flags | AntImageDescriptor.HAS_WARNINGS;
483         }
484         if(importNode != null || isExternal()){
485             flags = flags | AntImageDescriptor.IMPORTED;
486         }
487         ImageDescriptor base= getBaseImageDescriptor();
488         return AntUIImages.getImage(new AntImageDescriptor(base, flags));
489     }
490
491     protected ImageDescriptor getBaseImageDescriptor() {
492         return AntUIImages.getImageDescriptor(IAntUIConstants.IMG_TASK_PROPOSAL);
493     }
494     
495     protected AntModel getAntModel() {
496         AntElementNode parentNode= getParentNode();
497         while (!(parentNode instanceof AntProjectNode)) {
498             parentNode= parentNode.getParentNode();
499         }
500         return parentNode.getAntModel();
501     }
502
503     /**
504      * Sets the problem associated with this element
505      * @param problem The problem associated with this element.
506      */

507     public void associatedProblem(IProblem problem) {
508         fProblem= problem;
509     }
510
511     protected void appendEntityName(StringBuffer JavaDoc displayName) {
512         String JavaDoc path= getFilePath();
513         
514         if (getImportNode() != null) {
515             displayName.append(MessageFormat.format(AntModelMessages.getString("AntElementNode.9"), new String JavaDoc[]{getImportNode().getLabel()})); //$NON-NLS-1$
516
} else {
517             String JavaDoc entityName= getAntModel().getEntityName(path);
518             displayName.append(MessageFormat.format(AntModelMessages.getString("AntElementNode.9"), new String JavaDoc[]{entityName})); //$NON-NLS-1$
519
}
520     }
521     
522     public AntElementNode getImportNode() {
523         return importNode;
524     }
525     
526     public void setImportNode(AntElementNode importNode) {
527         this.importNode = importNode;
528     }
529     
530     public boolean hasChildren() {
531         if (childNodes == null) {
532             return false;
533         }
534         return !childNodes.isEmpty();
535     }
536
537     public void reset() {
538         childNodes= null;
539     }
540
541     public void setExternalInfo(int line, int column) {
542         fLine= line;
543         fColumn= column;
544     }
545     
546     public int[] getExternalInfo() {
547         return new int[] {fLine, fColumn};
548     }
549     
550     /**
551      * Return the resource that contains the definition of this
552      * Ant node.
553      * @return The resource that contains the definition of this ant node or <code>null</code>
554      * if that resource could not be determined (a buildfile that is external to the workspace).
555      */

556     public IFile getIFile() {
557         if (isExternal()) {
558             return AntUtil.getFileForLocation(filePath, null);
559         }
560         return getBuildFileResource();
561     }
562     
563     /**
564      * Return the resource that is the main build file for this
565      * Ant node.
566      * @return The resource that is the main buildfile for this ant node or <code>null</code>
567      * if that resource could not be determined (a buildfile that is external to the workspace).
568      */

569     public IFile getBuildFileResource() {
570         LocationProvider locationProvider= getAntModel().getLocationProvider();
571         return locationProvider.getFile();
572     }
573
574     /* (non-Javadoc)
575      * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
576      */

577     public Object JavaDoc getAdapter(Class JavaDoc adapter) {
578         return Platform.getAdapterManager().getAdapter(this, adapter);
579     }
580 }
Popular Tags