|
What this is
This file is included in the DevDaily.com
"Java Source Code
Warehouse" project. The intent of this project is to help you "Learn
Java by Example" TM.
Other links
The source code
/*
* Sun Public License Notice
*
* The contents of this file are subject to the Sun Public License
* Version 1.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://www.sun.com/
*
* The Original Code is NetBeans. The Initial Developer of the Original
* Code is Sun Microsystems, Inc. Portions Copyright 1997-2004 Sun
* Microsystems, Inc. All Rights Reserved.
*/
package org.netbeans.modules.ant.freeform;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import javax.swing.AbstractAction;
import javax.swing.Action;
import org.apache.tools.ant.module.api.support.ActionUtils;
import org.netbeans.spi.project.ActionProvider;
import org.netbeans.spi.project.support.ant.AntProjectHelper;
import org.netbeans.spi.project.ui.support.CommonProjectActions;
import org.netbeans.spi.project.ui.support.ProjectSensitiveActions;
import org.openide.ErrorManager;
import org.openide.actions.FindAction;
import org.openide.actions.ToolsAction;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.loaders.DataObject;
import org.openide.util.Lookup;
import org.openide.util.NbBundle;
import org.openide.util.actions.SystemAction;
import org.w3c.dom.Element;
/**
* Action bindings for a freeform project.
* @author Jesse Glick
*/
public final class Actions implements ActionProvider {
private final FreeformProject project;
public Actions(FreeformProject project) {
this.project = project;
}
public String[] getSupportedActions() {
Element genldata = project.helper().getPrimaryConfigurationData(true);
Element actionsEl = Util.findElement(genldata, "ide-actions", FreeformProjectType.NS_GENERAL); // NOI18N
if (actionsEl == null) {
return new String[0];
}
List/**/ actions = Util.findSubElements(actionsEl);
// Use a set, not a list, since when using context you can define one action several times:
Set/**/ names = new LinkedHashSet(actions.size());
Iterator it = actions.iterator();
while (it.hasNext()) {
Element actionEl = (Element)it.next();
names.add(actionEl.getAttribute("name")); // NOI18N
}
return (String[])names.toArray(new String[names.size()]);
}
public boolean isActionEnabled(String command, Lookup context) throws IllegalArgumentException {
Element genldata = project.helper().getPrimaryConfigurationData(true);
Element actionsEl = Util.findElement(genldata, "ide-actions", FreeformProjectType.NS_GENERAL); // NOI18N
if (actionsEl == null) {
throw new IllegalArgumentException("No commands supported"); // NOI18N
}
List/**/ actions = Util.findSubElements(actionsEl);
Iterator it = actions.iterator();
boolean foundAction = false;
while (it.hasNext()) {
Element actionEl = (Element)it.next();
if (actionEl.getAttribute("name").equals(command)) { // NOI18N
foundAction = true;
// XXX perhaps check also existence of script
Element contextEl = Util.findElement(actionEl, "context", FreeformProjectType.NS_GENERAL); // NOI18N
if (contextEl != null) {
// Check whether the context contains files all in this folder,
// matching the pattern if any, and matching the arity (single/multiple).
Map/**/ selection = findSelection(contextEl, context, project);
if (selection.size() == 1) {
// Definitely enabled.
return true;
} else if (!selection.isEmpty()) {
// Multiple selection; check arity.
Element arityEl = Util.findElement(contextEl, "arity", FreeformProjectType.NS_GENERAL); // NOI18N
assert arityEl != null : "No in for " + command;
if (Util.findElement(arityEl, "separated-files", FreeformProjectType.NS_GENERAL) != null) { // NOI18N
// Supports multiple selection, take it.
return true;
}
}
} else {
// Not context-sensitive.
return true;
}
}
}
if (foundAction) {
// Was at least one context-aware variant but did not match.
return false;
} else {
throw new IllegalArgumentException("Unrecognized command: " + command); // NOI18N
}
}
public void invokeAction(String command, Lookup context) throws IllegalArgumentException {
Element genldata = project.helper().getPrimaryConfigurationData(true);
Element actionsEl = Util.findElement(genldata, "ide-actions", FreeformProjectType.NS_GENERAL); // NOI18N
if (actionsEl == null) {
throw new IllegalArgumentException("No commands supported"); // NOI18N
}
List/**/ actions = Util.findSubElements(actionsEl);
Iterator it = actions.iterator();
boolean foundAction = false;
while (it.hasNext()) {
Element actionEl = (Element)it.next();
if (actionEl.getAttribute("name").equals(command)) { // NOI18N
foundAction = true;
runConfiguredAction(project, actionEl, context);
}
}
if (!foundAction) {
throw new IllegalArgumentException("Unrecognized command: " + command); // NOI18N
}
}
/**
* Find a file selection in a lookup context based on a project.xml declaration.
* If all DataObject's (or FileObject's) in the lookup match the folder named in the declaration,
* and match any optional pattern declaration, then they are returned as a map from relative
* path to actual file object. Otherwise an empty map is returned.
*/
private static Map/**/ findSelection(Element contextEl, Lookup context, FreeformProject project) {
Collection/**/ files = context.lookup(new Lookup.Template(FileObject.class)).allInstances();
if (files.isEmpty()) {
// Try again with DataObject's.
Collection/**/ filesDO = context.lookup(new Lookup.Template(DataObject.class)).allInstances();
if (filesDO.isEmpty()) {
return Collections.EMPTY_MAP;
}
files = new ArrayList(filesDO.size());
Iterator it = filesDO.iterator();
while (it.hasNext()) {
files.add(((DataObject) it.next()).getPrimaryFile());
}
}
Element folderEl = Util.findElement(contextEl, "folder", FreeformProjectType.NS_GENERAL); // NOI18N
assert folderEl != null : "Must have in ";
String rawtext = Util.findText(folderEl);
assert rawtext != null : "Must have text contents in ";
String evaltext = project.evaluator().evaluate(rawtext);
if (evaltext == null) {
return Collections.EMPTY_MAP;
}
FileObject folder = project.helper().resolveFileObject(evaltext);
if (folder == null) {
return Collections.EMPTY_MAP;
}
Pattern pattern = null;
Element patternEl = Util.findElement(contextEl, "pattern", FreeformProjectType.NS_GENERAL); // NOI18N
if (patternEl != null) {
String text = Util.findText(patternEl);
assert text != null : "Must have text contents in ";
try {
pattern = Pattern.compile(text);
} catch (PatternSyntaxException e) {
Util.err.annotate(e, ErrorManager.UNKNOWN, "From in " + FileUtil.getFileDisplayName(project.getProjectDirectory().getFileObject(AntProjectHelper.PROJECT_XML_PATH)), null, null, null); // NOI18N
Util.err.notify(e);
return Collections.EMPTY_MAP;
}
}
Map/**/ result = new HashMap();
Iterator it = files.iterator();
while (it.hasNext()) {
FileObject file = (FileObject) it.next();
String path = FileUtil.getRelativePath(folder, file);
if (path == null) {
return Collections.EMPTY_MAP;
}
if (pattern != null && !pattern.matcher(path).find()) {
return Collections.EMPTY_MAP;
}
result.put(path, file);
}
return result;
}
/**
* Run a project action as described by subelements
|