/*
* 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
Copyright 1998-2008 Alvin Alexander
All Rights Reserved.
devdaily.com is based in louisville, kentucky, and this web site is hosted by godaddy.com