KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > module > nodes > AntTargetNode


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.apache.tools.ant.module.nodes;
21
22
23 import java.awt.Toolkit JavaDoc;
24 import java.awt.event.ActionEvent JavaDoc;
25 import java.io.IOException JavaDoc;
26 import javax.swing.AbstractAction JavaDoc;
27 import javax.swing.Action JavaDoc;
28 import javax.swing.UIManager JavaDoc;
29 import javax.swing.event.ChangeEvent JavaDoc;
30 import javax.swing.event.ChangeListener JavaDoc;
31 import javax.swing.text.StyledDocument JavaDoc;
32 import javax.xml.parsers.SAXParser JavaDoc;
33 import javax.xml.parsers.SAXParserFactory JavaDoc;
34 import org.apache.tools.ant.module.AntModule;
35 import org.apache.tools.ant.module.api.AntProjectCookie;
36 import org.apache.tools.ant.module.api.support.TargetLister;
37 import org.apache.tools.ant.module.run.TargetExecutor;
38 import org.apache.tools.ant.module.wizards.shortcut.ShortcutWizard;
39 import org.apache.tools.ant.module.xml.AntProjectSupport;
40 import org.openide.ErrorManager;
41 import org.openide.actions.OpenAction;
42 import org.openide.actions.PropertiesAction;
43 import org.openide.cookies.EditorCookie;
44 import org.openide.cookies.LineCookie;
45 import org.openide.cookies.OpenCookie;
46 import org.openide.filesystems.FileObject;
47 import org.openide.loaders.DataObject;
48 import org.openide.loaders.DataObjectNotFoundException;
49 import org.openide.nodes.AbstractNode;
50 import org.openide.nodes.Children;
51 import org.openide.nodes.PropertySupport;
52 import org.openide.nodes.Sheet;
53 import org.openide.text.Line;
54 import org.openide.util.NbBundle;
55 import org.openide.util.WeakListeners;
56 import org.openide.util.actions.SystemAction;
57 import org.xml.sax.Attributes JavaDoc;
58 import org.xml.sax.InputSource JavaDoc;
59 import org.xml.sax.Locator JavaDoc;
60 import org.xml.sax.SAXException JavaDoc;
61 import org.xml.sax.helpers.DefaultHandler JavaDoc;
62
63 final class AntTargetNode extends AbstractNode implements ChangeListener JavaDoc {
64     
65     /** main project, not necessarily the one defining this target */
66     private final AntProjectCookie project;
67     private final TargetLister.Target target;
68     
69     /**
70      * Create a new target node.
71      * @param project the <em>main</em> project with this target (may not be the project this is physically part of)
72      * @param target a representation of this target
73      * @param allTargets all other targets in the main project
74      */

75     public AntTargetNode(AntProjectCookie project, TargetLister.Target target) {
76         super(Children.LEAF);
77         this.project = project;
78         assert !target.isOverridden() : "Cannot include overridden targets";
79         this.target = target;
80         target.getScript().addChangeListener(WeakListeners.change(this, target.getScript()));
81         setName(target.getQualifiedName());
82         setDisplayName(target.getName());
83         if (target.isDescribed()) {
84             setShortDescription(target.getElement().getAttribute("description")); // NOI18N
85
setIconBaseWithExtension("org/apache/tools/ant/module/resources/EmphasizedTargetIcon.gif");
86         } else if (target.isDefault()) {
87             setIconBaseWithExtension("org/apache/tools/ant/module/resources/EmphasizedTargetIcon.gif");
88         } else {
89             setIconBaseWithExtension("org/apache/tools/ant/module/resources/TargetIcon.gif");
90         }
91         getCookieSet().add(new TargetOpenCookie(target));
92     }
93     
94     private static String JavaDoc internalTargetColor = null;
95     /** Loosely copied from VcsFileSystem.annotateNameHtml */
96     private static synchronized String JavaDoc getInternalTargetColor() {
97         if (internalTargetColor == null) {
98             if (UIManager.getDefaults().getColor("Tree.selectionBackground").equals(UIManager.getDefaults().getColor("controlShadow"))) { // NOI18N
99
internalTargetColor = "Tree.selectionBorderColor"; // NOI18N
100
} else {
101                 internalTargetColor = "controlShadow"; // NOI18N
102
}
103         }
104         return internalTargetColor;
105     }
106     
107     @Override JavaDoc
108     public String JavaDoc getHtmlDisplayName() {
109         // Use markup to indicate the default target, imported targets, and internal targets.
110
boolean imported = target.getScript() != project;
111         if (!imported && !target.isDefault() && !target.isInternal()) {
112             return null;
113         }
114         StringBuffer JavaDoc name = new StringBuffer JavaDoc(target.getName());
115         if (imported) {
116             name.insert(0, "<i>"); // NOI18N
117
name.append("</i>"); // NOI18N
118
}
119         if (target.isDefault()) {
120             name.insert(0, "<b>"); // NOI18N
121
name.append("</b>"); // NOI18N
122
}
123         if (target.isInternal()) {
124             name.insert(0, "'>"); // NOI18N
125
name.insert(0, getInternalTargetColor());
126             name.insert(0, "<font color='!"); // NOI18N
127
name.append("</font>"); // NOI18N
128
}
129         return name.toString();
130     }
131     
132     public void stateChanged (ChangeEvent JavaDoc ev) {
133         firePropertyChange (null, null, null);
134     }
135
136     @Override JavaDoc
137     public boolean canDestroy () {
138         return false;
139     }
140     
141     @Override JavaDoc
142     public boolean canRename () {
143         return false;
144     }
145     
146     @Override JavaDoc
147     public boolean canCopy () {
148         return true;
149     }
150     
151     @Override JavaDoc
152     public boolean canCut () {
153         return false;
154     }
155     
156     private final Action JavaDoc EXECUTE = new ExecuteAction();
157     private final Action JavaDoc CREATE_SHORTCUT = new CreateShortcutAction();
158
159     @Override JavaDoc
160     public Action JavaDoc[] getActions(boolean context) {
161         if (!target.isInternal()) {
162             return new Action JavaDoc[] {
163                 SystemAction.get(OpenAction.class),
164                 null,
165                 EXECUTE,
166                 CREATE_SHORTCUT,
167                 null,
168                 SystemAction.get(PropertiesAction.class),
169             };
170         } else {
171             return new Action JavaDoc[] {
172                 SystemAction.get(OpenAction.class),
173                 null,
174                 SystemAction.get(PropertiesAction.class),
175             };
176         }
177     }
178
179     @Override JavaDoc
180     public Action JavaDoc getPreferredAction() {
181         return SystemAction.get(OpenAction.class);
182     }
183     
184     private final class ExecuteAction extends AbstractAction JavaDoc {
185         
186         ExecuteAction() {
187             super(NbBundle.getMessage(AntTargetNode.class, "LBL_execute_target"));
188         }
189         
190         public void actionPerformed(ActionEvent JavaDoc e) {
191             try {
192                 TargetExecutor te = new TargetExecutor(project, new String JavaDoc[] {target.getName()});
193                 te.execute();
194             } catch (IOException JavaDoc ioe) {
195                 AntModule.err.notify(ioe);
196             }
197         }
198         
199     }
200     
201     /**
202      * Action to invoke the target shortcut wizard.
203      * Used to be a "template", but this is more natural.
204      * @see "issue #37374"
205      */

206     private final class CreateShortcutAction extends AbstractAction JavaDoc {
207         
208         CreateShortcutAction() {
209             super(NbBundle.getMessage(AntTargetNode.class, "LBL_create_shortcut"));
210         }
211         
212         public void actionPerformed(ActionEvent JavaDoc e) {
213             ShortcutWizard.show(project, target.getElement());
214         }
215         
216     }
217
218     @Override JavaDoc
219     protected Sheet createSheet() {
220         Sheet sheet = super.createSheet ();
221         Sheet.Set props = sheet.get (Sheet.PROPERTIES);
222         if (props == null) {
223             props = Sheet.createPropertiesSet();
224             sheet.put(props);
225         }
226         String JavaDoc[] attrs = new String JavaDoc[] {"name", "description", "depends"}; // NOI18N
227
for (String JavaDoc attr : attrs) {
228             org.openide.nodes.Node.Property<?> prop = new AntProperty(target.getElement(), attr);
229             prop.setDisplayName (NbBundle.getMessage (AntTargetNode.class, "PROP_target_" + attr));
230             prop.setShortDescription (NbBundle.getMessage (AntTargetNode.class, "HINT_target_" + attr));
231             props.put (prop);
232         }
233         /*XXX
234         props.put (new BuildSequenceProperty());
235          */

236         return sheet;
237     }
238     
239     /**
240      * Node displaying the sequence of all called targets when executing.
241      */

242     private final class BuildSequenceProperty extends PropertySupport.ReadOnly<String JavaDoc> {
243         
244         /** Creates new BuildSequenceProperty.
245          */

246         public BuildSequenceProperty() {
247             super ("buildSequence", // NOI18N
248
String JavaDoc.class,
249                    NbBundle.getMessage (AntTargetNode.class, "PROP_target_sequence"),
250                    NbBundle.getMessage (AntTargetNode.class, "HINT_target_sequence")
251                   );
252         }
253
254         /** Computes the dependencies of all called targets and returns an ordered
255          * sequence String.
256          * @param target the target that gets executed
257          * /
258         protected String computeTargetDependencies(org.w3c.dom.Element target) {
259             if (target == null) {
260                 return "";
261             }
262             
263             // get ProjectElement
264             Element proj = (Element) target.getParentNode ();
265             if (proj == null) {
266                 // just return current target name
267                 return target.getAttribute ("name"); // NOI18N
268             } else {
269                 // List with all called targets. the last called target is the first
270                 // in the list
271                 List callingList = new LinkedList();
272                 // add this target.
273                 callingList = addTarget (callingList, target, 0, proj);
274                 if (callingList != null) {
275                     return getReverseString (callingList);
276                 } else {
277                     return NbBundle.getMessage (AntProjectNode.class, "MSG_target_sequence_illegaldepends");
278                 }
279             }
280         }
281
282         /** Adds a target to the List. Calls depends-on targets recursively.
283          * @param runningList List containing the ordered targets.
284          * @param target the target that should be added
285          * @param pos position where this target should be inserted
286          * @projectElement the Element of the Ant project.
287          *
288          * @return list with all targets or null if a target was not found.
289          * /
290         protected List addTarget(List runningList, Element target, int pos, Element projectElement) {
291             String targetName = target.getAttribute ("name"); // NOI18N
292             if (targetName == null) return runningList;
293             
294             // search target, skip it if found
295             Iterator it = runningList.iterator();
296             while (it.hasNext()) {
297                 if (targetName.equals (it.next())) {
298                     return runningList;
299                 }
300             }
301             //add target at the given position...
302             runningList.add(pos, targetName);
303             
304             // check dependenciesList
305             String dependsString = target.getAttribute ("depends"); // NOI18N
306             if (dependsString == null) return runningList;
307             
308             // add each target of the dependencies List
309             StringTokenizer st = new StringTokenizer(dependsString, ", "); // NOI18N
310             while (st.hasMoreTokens() && runningList != null) {
311                 Element dependsTarget = getTargetElement(st.nextToken(), projectElement);
312                 if (dependsTarget != null) {
313                     runningList = addTarget(runningList, dependsTarget, (pos + 1), projectElement);
314                 } else {
315                     // target is missing, we return null to indicate that something is wrong
316                     return null;
317                 }
318             }
319             
320             return runningList;
321         }
322         
323         /** Returns the Element of a target given by its name. * /
324         protected Element getTargetElement(String targetName, Element projectElement) {
325             NodeList nl = projectElement.getChildNodes();
326             for (int i = 0; i < nl.getLength (); i++) {
327                 if (nl.item (i) instanceof Element) {
328                     Element el = (Element) nl.item (i);
329                     if (el.getTagName().equals("target") && el.getAttribute("name").equals(targetName)) { // NOI18N
330                         return el;
331                     }
332                 }
333             }
334             return null;
335         }
336  
337         /** Returns a String of all Elements in the List in reverse order. * /
338         protected String getReverseString (List l) {
339             StringBuffer sb = new StringBuffer ();
340             for (int x= (l.size() - 1); x > -1; x--) {
341                 sb.append (l.get(x));
342                 if (x > 0) sb.append (", "); // NOI18N
343             }
344             return sb.toString ();
345         }
346         
347         /** Returns the value of this property. */

348         @Override JavaDoc
349         public String JavaDoc getValue () {
350             /*XXX
351             return computeTargetDependencies(getTarget());
352              */

353             return "XXX BuildSequenceProperty currently unimplemented";
354         }
355     }
356     
357     private static final class TargetOpenCookie implements OpenCookie {
358         
359         private final TargetLister.Target target;
360         
361         public TargetOpenCookie(TargetLister.Target target) {
362             this.target = target;
363         }
364         
365         public void open() {
366             if (target.getScript().getParseException() != null) {
367                 Toolkit.getDefaultToolkit().beep();
368                 return;
369             }
370             FileObject script = target.getScript().getFileObject();
371             assert script != null : "No build script for " + target;
372             EditorCookie editor;
373             LineCookie lines;
374             try {
375                 DataObject d = DataObject.find(script);
376                 editor = d.getCookie(EditorCookie.class);
377                 lines = d.getCookie(LineCookie.class);
378                 assert editor != null;
379                 assert lines != null;
380             } catch (DataObjectNotFoundException e) {
381                 throw new AssertionError JavaDoc(e);
382             }
383             try {
384                 StyledDocument JavaDoc doc = editor.openDocument();
385                 InputSource JavaDoc in = AntProjectSupport.createInputSource(script, doc);
386                 SAXParserFactory JavaDoc factory = SAXParserFactory.newInstance();
387                 SAXParser JavaDoc parser = factory.newSAXParser();
388                 final int[] line = new int[1];
389                 final String JavaDoc name = target.getName();
390                 class Handler extends DefaultHandler JavaDoc {
391                     private Locator JavaDoc locator;
392                     @Override JavaDoc
393                     public void setDocumentLocator(Locator JavaDoc l) {
394                         locator = l;
395                     }
396                     @Override JavaDoc
397                     public void startElement(String JavaDoc uri, String JavaDoc localname, String JavaDoc qname, Attributes JavaDoc attr) throws SAXException JavaDoc {
398                         if (line[0] == 0) {
399                             if (qname.equals("target") && name.equals(attr.getValue("name"))) { // NOI18N
400
line[0] = locator.getLineNumber();
401                             }
402                         }
403                     }
404                 }
405                 parser.parse(in, new Handler JavaDoc());
406                 if (line[0] < 1) {
407                     Toolkit.getDefaultToolkit().beep();
408                     return;
409                 }
410                 lines.getLineSet().getCurrent(line[0] - 1).show(Line.SHOW_GOTO);
411             } catch (Exception JavaDoc e) {
412                 AntModule.err.notify(ErrorManager.INFORMATIONAL, e);
413                 return;
414             }
415         }
416         
417     }
418     
419 }
420
Popular Tags