blob: c50725f79f03827734fa38fd8c3c5ca54f7ac323 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.modules.web.freeform;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.netbeans.api.java.project.JavaProjectConstants;
import org.netbeans.api.project.Project;
import org.netbeans.api.project.ProjectInformation;
import org.netbeans.api.project.ProjectManager;
import org.netbeans.api.project.ProjectUtils;
import org.netbeans.modules.ant.freeform.spi.support.Util;
import org.netbeans.modules.web.api.webmodule.WebProjectConstants;
import org.netbeans.spi.project.ActionProvider;
import org.netbeans.spi.project.AuxiliaryConfiguration;
import org.netbeans.spi.project.support.ant.AntProjectHelper;
import org.netbeans.spi.project.support.ant.EditableProperties;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.cookies.EditCookie;
import org.openide.cookies.LineCookie;
import org.openide.filesystems.FileLock;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.loaders.DataObject;
import org.openide.loaders.DataObjectNotFoundException;
import org.openide.text.Line.ShowOpenType;
import org.openide.text.Line.ShowVisibilityType;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle;
import org.openide.xml.XMLUtil;
import org.w3c.dom.Comment;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
* Handles providing implementations of some Web-oriented IDE-specific actions.
*
* @author Libor Kotouc
*/
public class WebFreeFormActionProvider implements ActionProvider {
/**
* Script to hold file-sensitive generated targets like compile.single.
* (Or for generated targets for debug which cannot reuse any existing target body.)
* These pick up at least project.dir from project.xml and the entire
* target body is fixed by the IDE, except for some strings determined
* by information from project.xml like the classpath. The basedir
* is set to the project directory so that properties match their
* semantics in project.xml.
*/
static final String FILE_SCRIPT_PATH = "nbproject/ide-file-targets.xml"; // NOI18N
/**
* Script to hold non-file-sensitive generated targets like debug.
* These import the original build script and share its basedir, so that
* properties match the semantics of build.xml.
*/
static final String GENERAL_SCRIPT_PATH = "nbproject/ide-targets.xml"; // NOI18N
private static final String LOAD_PROPS_TARGET = "-load-props"; // NOI18N
private static final String CHECK_PROPS_TARGET = "-check-props"; // NOI18N
private static final String INIT_TARGET = "-init"; // NOI18N
private static final String DEBUG_TARGET = "debug-nb"; // NOI18N
private static final String DISPLAY_BROWSER = "debug-display-browser"; // NOI18N
private static final String[] DEBUG_PROPERTIES = new String[] {
WebFreeformProperties.JPDA_SESSION_NAME,
WebFreeformProperties.JPDA_HOST,
WebFreeformProperties.JPDA_ADDRESS,
WebFreeformProperties.JPDA_TRANSPORT,
WebFreeformProperties.DEBUG_SOURCEPATH,
WebFreeformProperties.CLIENT_URL
};
private static final String DEBUG_PROPERTIES_TEMPLATE = "/org/netbeans/modules/web/freeform/resources/debug-properties.template"; // NOI18N
private final Project project;
private final AntProjectHelper helper;
private final AuxiliaryConfiguration aux;
private static final String[] SUPPORTED_ACTIONS = {
ActionProvider.COMMAND_DEBUG,
};
/** Creates a new instance of WebFreeFormActionProvider */
public WebFreeFormActionProvider(Project aProject, AntProjectHelper aHelper, AuxiliaryConfiguration aAux) {
project = aProject;
helper = aHelper;
aux = aAux;
}
public boolean isActionEnabled(String command, org.openide.util.Lookup context) throws IllegalArgumentException {
boolean enabled = false;
if (command.equals(ActionProvider.COMMAND_DEBUG))
enabled = true;
return enabled;
}
public void invokeAction(String command, org.openide.util.Lookup context) throws IllegalArgumentException {
try {
try {
if (command.equals(ActionProvider.COMMAND_DEBUG))
handleDebug();
} catch (SAXException e) {
throw (IOException) new IOException(e.toString()).initCause(e);
}
} catch (IOException e) {
Exceptions.printStackTrace(e);
}
}
public String[] getSupportedActions() {
return SUPPORTED_ACTIONS;
}
private void handleDebug() throws IOException, SAXException {
//allow user to confirm target generation
if (!alert(NbBundle.getMessage(WebFreeFormActionProvider.class, "ACTION_debug"), GENERAL_SCRIPT_PATH))
return;
//let's generate a debug target
String propertiesFile = writeDebugProperties();
//read script document
Document script = readCustomScript(GENERAL_SCRIPT_PATH);
if (script == null) //script doesn't exist
script = createCustomScript();
//append comments and target
writeComments(script);
writeTargets(script, propertiesFile);
//save script
writeCustomScript(script, GENERAL_SCRIPT_PATH);
//write changes to project.xml
addBinding(ActionProvider.COMMAND_DEBUG, GENERAL_SCRIPT_PATH, DEBUG_TARGET, null, null, null, null, null);
//show the result
jumpToBinding(ActionProvider.COMMAND_DEBUG);
jumpToBuildScript(GENERAL_SCRIPT_PATH, DEBUG_TARGET);
openFile(propertiesFile);
}
/**
* Display an alert asking the user whether to really generate a target.
* @param commandDisplayName the display name of the action to be bound
* @param scriptPath the path that to the script that will be generated or written to
* @return true if IDE should proceed
*/
private boolean alert(String commandDisplayName, String scriptPath) {
String projectDisplayName = ProjectUtils.getInformation(project).getDisplayName();
String title = NbBundle.getMessage(WebFreeFormActionProvider.class, "TITLE_generate_target_dialog", commandDisplayName, projectDisplayName);
String body = NbBundle.getMessage(WebFreeFormActionProvider.class, "TEXT_generate_target_dialog", commandDisplayName, scriptPath);
NotifyDescriptor d = new NotifyDescriptor.Message(body, NotifyDescriptor.QUESTION_MESSAGE);
d.setTitle(title);
d.setOptionType(NotifyDescriptor.OK_CANCEL_OPTION);
JButton generate = new JButton(NbBundle.getMessage(WebFreeFormActionProvider.class, "LBL_generate"));
generate.setDefaultCapable(true);
d.setOptions(new Object[] {generate, NotifyDescriptor.CANCEL_OPTION});
return DialogDisplayer.getDefault().notify(d) == generate;
}
/**
* Reads a generated script if it exists, else create a skeleton.
* @param scriptPath e.g. {@link #FILE_SCRIPT_PATH} or {@link #GENERAL_SCRIPT_PATH}
* @return script document.
*/
Document readCustomScript(String scriptPath) throws IOException, SAXException {
Document script = null;
FileObject scriptFile = helper.getProjectDirectory().getFileObject(scriptPath);
if (scriptFile != null) {
InputStream is = scriptFile.getInputStream();
try {
script = XMLUtil.parse(new InputSource(is), false, true, null, null);
} finally {
is.close();
}
}
return script;
}
/**
* Creates custom script.
* @return script document.
*/
Document createCustomScript() {
//create document, set root and its attributes
Document script = XMLUtil.createDocument("project", null, null, null); // NOI18N
Element scriptRoot = script.getDocumentElement();
scriptRoot.setAttribute("basedir", /* ".." times count('/', FILE_SCRIPT_PATH) */".."); // NOI18N
String projname = ProjectUtils.getInformation(project).getDisplayName();
scriptRoot.setAttribute("name", NbBundle.getMessage(WebFreeFormActionProvider.class, "LBL_generated_script_name", projname));
//copy properties from project.xml to the script
copyProperties(Util.getPrimaryConfigurationData(helper), scriptRoot);
return script;
}
/**
* Copies all properties defined in project.xml to Ant syntax.
* Used for generated targets which essentially copy Ant fragments from project.xml
* (rather than the user's build.xml).
* @param config XML of an Ant project (document element)
* @param script target custom script
*/
private void copyProperties(Element config, Element script) {
// Look for <properties> in project.xml and make corresponding definitions in the Ant script.
// See corresponding schema.
Element data = Util.getPrimaryConfigurationData(helper);
Element properties = XMLUtil.findElement(data, "properties", Util.NAMESPACE); // NOI18N
if (properties != null) {
Iterator<Element> propertiesIt = XMLUtil.findSubElements(properties).iterator();
while (propertiesIt.hasNext()) {
Element el = (Element) propertiesIt.next();
Element nue = script.getOwnerDocument().createElement("property"); // NOI18N
if (el.getLocalName().equals("property")) { // NOI18N
String name = el.getAttribute("name"); // NOI18N
assert name != null;
String text = XMLUtil.findText(el);
assert text != null;
nue.setAttribute("name", name); // NOI18N
nue.setAttribute("value", text); // NOI18N
} else if (el.getLocalName().equals("property-file")) { // NOI18N
String text = XMLUtil.findText(el);
assert text != null;
nue.setAttribute("file", text); // NOI18N
} else {
assert false : el;
}
script.appendChild(nue);
}
}
}
/**
* Appends the comments to script.
* @param script Script to write to.
*/
private void writeComments(Document script) {
Comment comm4Edit = script.createComment(" " + NbBundle.getMessage(WebFreeFormActionProvider.class, "COMMENT_edit_target") + " "); // NOI18N
Comment comm4Info = script.createComment(" " + NbBundle.getMessage(WebFreeFormActionProvider.class, "COMMENT_more_info_debug") + " "); // NOI18N
Element scriptRoot = script.getDocumentElement();
scriptRoot.appendChild(comm4Edit);
scriptRoot.appendChild(comm4Info);
}
/**
* Appends necessary targets to script.
* @param script Script to write to.
*/
private void writeTargets(Document script, String propertiesFile) {
createLoadPropertiesTarget(script, propertiesFile);
createCheckPropertiesTarget(script);
createInitTarget(script);
createDebugTarget(script);
createDisplayBrowserTarget(script);
}
/**
* Creates target:
* <target name="-load-props">
* <property file="nbproject/project.properties"/>
* </target>
* @param script Script to write to.
*/
private void createLoadPropertiesTarget(Document script, String propertiesFile) {
Element target = script.createElement("target"); // NOI18N
target.setAttribute("name", LOAD_PROPS_TARGET); // NOI18N
Element property = script.createElement("property"); // NOI18N
property.setAttribute("file", propertiesFile);// NOI18N
target.appendChild(property);
script.getDocumentElement().appendChild(target);
}
/**
* Creates target:
* <target name="-check-props">
* <fail unless="jpda.session.name"/>
* <fail unless="jpda.host"/>
* <fail unless="jpda.address"/>
* <fail unless="jpda.transport"/>
* <fail unless="debug.sourcepath"/>
* <fail unless="client.url"/>
* </target>
* @param script Script to write to.
*/
private void createCheckPropertiesTarget(Document script) {
Element target = script.createElement("target"); // NOI18N
target.setAttribute("name", CHECK_PROPS_TARGET); // NOI18N
Element fail;
for (int i = 0; i < DEBUG_PROPERTIES.length; i++) {
fail = script.createElement("fail"); // NOI18N
fail.setAttribute("unless", DEBUG_PROPERTIES[i]); // NOI18N
target.appendChild(fail);
}
script.getDocumentElement().appendChild(target);
}
/**
* Creates target:
* <target name="-init" depends="-load-props, -check-props"/>
* @param script Script to write to.
*/
private void createInitTarget(Document script) {
Element target = script.createElement("target"); // NOI18N
target.setAttribute("name", INIT_TARGET); // NOI18N
target.setAttribute("depends", LOAD_PROPS_TARGET + ", " + CHECK_PROPS_TARGET); // NOI18N
script.getDocumentElement().appendChild(target);
}
/**
* Creates target:
* <target name="debug-nb" depends="-init" if="netbeans.home">
* <nbjpdaconnect name="${session.name}" host="${jpda.host}" address="${jpda.address}" transport="${jpda.transport}">
* <sourcepath>
* <path path="${debug.sourcepath}"/>
* </sourcepath>
* </nbjpdaconnect>
* <antcall target="debug-display-browser"/>
* </target>
* @param script Script to write to.
*/
private void createDebugTarget(Document script) {
Element target = script.createElement("target");
target.setAttribute("name", DEBUG_TARGET); // NOI18N
target.setAttribute("depends", INIT_TARGET); // NOI18N
target.setAttribute("if", "netbeans.home"); // NOI18N
Element nbjpdaconnect = script.createElement("nbjpdaconnect"); // NOI18N
nbjpdaconnect.setAttribute("name", "${" + WebFreeformProperties.JPDA_SESSION_NAME + "}"); // NOI18N
nbjpdaconnect.setAttribute("host", "${" + WebFreeformProperties.JPDA_HOST + "}"); // NOI18N
nbjpdaconnect.setAttribute("address", "${" + WebFreeformProperties.JPDA_ADDRESS + "}"); // NOI18N
nbjpdaconnect.setAttribute("transport", "${" + WebFreeformProperties.JPDA_TRANSPORT + "}"); // NOI18N
Element sourcepath = script.createElement("sourcepath"); // NOI18N
Element path = script.createElement("path"); // NOI18N
path.setAttribute("path", "${debug.sourcepath}"); // NOI18N
sourcepath.appendChild(path);
nbjpdaconnect.appendChild(sourcepath);
target.appendChild(nbjpdaconnect);
Element antcall = script.createElement("antcall"); // NOI18N
antcall.setAttribute("target", DISPLAY_BROWSER); // NOI18N
target.appendChild(antcall);
script.getDocumentElement().appendChild(target);
}
/**
* Creates target:
* <target name="debug-display-browser">
* <nbbrowse url="${client.url}"/>
* </target>
* @param script Script to write to.
*/
private void createDisplayBrowserTarget(Document script) {
Element target = script.createElement("target"); // NOI18N
target.setAttribute("name", DISPLAY_BROWSER); // NOI18N
Element nbbrowse = script.createElement("nbbrowse"); // NOI18N
nbbrowse.setAttribute("url", "${client.url}"); // NOI18N
target.appendChild(nbbrowse);
script.getDocumentElement().appendChild(target);
}
/**
* Write a script with a new or modified document.
* @param script Document written to the script path.
* @param scriptPath e.g. {@link #FILE_SCRIPT_PATH} or {@link #GENERAL_SCRIPT_PATH}
*/
void writeCustomScript(Document script, String scriptPath) throws IOException {
FileObject scriptFile = helper.getProjectDirectory().getFileObject(scriptPath);
if (scriptFile == null) {
scriptFile = FileUtil.createData(helper.getProjectDirectory(), scriptPath);
}
FileLock lock = scriptFile.lock();
try {
OutputStream os = scriptFile.getOutputStream(lock);
try {
XMLUtil.write(script, os, "UTF-8"); // NOI18N
} finally {
os.close();
}
} finally {
lock.releaseLock();
}
}
/**
* Add an action binding to project.xml.
* If there is no required context, the action is also added to the context menu of the project node.
* @param command the command name
* @param scriptPath the path to the generated script
* @param target the name of the target (in scriptPath)
* @param propertyName a property name to hold the selection (or null for no context, in which case remainder should be null)
* @param dir the raw text to use for the directory name
* @param pattern the regular expression to match, or null
* @param format the format to use
* @param separator the separator to use for multiple files, or null for single file only
*/
void addBinding(String command, String scriptPath, String target, String propertyName, String dir, String pattern, String format, String separator) throws IOException {
// XXX cannot use FreeformProjectGenerator since that is currently not a public support SPI from ant/freeform
// XXX should this try to find an existing binding? probably not, since it is assumed that if there was one, we would never get here to begin with
Element data = Util.getPrimaryConfigurationData(helper);
Element ideActions = XMLUtil.findElement(data, "ide-actions", Util.NAMESPACE); // NOI18N
if (ideActions == null) {
// Probably won't happen, since generator produces it always.
// Not trivial to just add it now, since order is significant in the schema. (FPG deals with these things.)
return;
}
Document doc = data.getOwnerDocument();
Element action = doc.createElementNS(Util.NAMESPACE, "action"); // NOI18N
action.setAttribute("name", command); // NOI18N
Element script = doc.createElementNS(Util.NAMESPACE, "script"); // NOI18N
script.appendChild(doc.createTextNode(scriptPath));
action.appendChild(script);
Element targetEl = doc.createElementNS(Util.NAMESPACE, "target"); // NOI18N
targetEl.appendChild(doc.createTextNode(target));
action.appendChild(targetEl);
ideActions.appendChild(action);
if (propertyName != null) {
Element context = doc.createElementNS(Util.NAMESPACE, "context"); // NOI18N
Element property = doc.createElementNS(Util.NAMESPACE, "property"); // NOI18N
property.appendChild(doc.createTextNode(propertyName));
context.appendChild(property);
Element folder = doc.createElementNS(Util.NAMESPACE, "folder"); // NOI18N
folder.appendChild(doc.createTextNode(dir));
context.appendChild(folder);
if (pattern != null) {
Element patternEl = doc.createElementNS(Util.NAMESPACE, "pattern"); // NOI18N
patternEl.appendChild(doc.createTextNode(pattern));
context.appendChild(patternEl);
}
Element formatEl = doc.createElementNS(Util.NAMESPACE, "format"); // NOI18N
formatEl.appendChild(doc.createTextNode(format));
context.appendChild(formatEl);
Element arity = doc.createElementNS(Util.NAMESPACE, "arity"); // NOI18N
if (separator != null) {
Element separatorEl = doc.createElementNS(Util.NAMESPACE, "separated-files"); // NOI18N
separatorEl.appendChild(doc.createTextNode(separator));
arity.appendChild(separatorEl);
} else {
arity.appendChild(doc.createElementNS(Util.NAMESPACE, "one-file-only")); // NOI18N
}
context.appendChild(arity);
action.appendChild(context);
} else {
// Add a context menu item, since it applies to the project as a whole.
// Assume there is already a <context-menu> defined, which is quite likely.
Element view = XMLUtil.findElement(data, "view", Util.NAMESPACE); // NOI18N
if (view != null) {
Element contextMenu = XMLUtil.findElement(view, "context-menu", Util.NAMESPACE); // NOI18N
if (contextMenu != null) {
Element ideAction = doc.createElementNS(Util.NAMESPACE, "ide-action"); // NOI18N
ideAction.setAttribute("name", command); // NOI18N
contextMenu.appendChild(ideAction);
}
}
}
Util.putPrimaryConfigurationData(helper, data);
ProjectManager.getDefault().saveProject(project);
}
private String writeDebugProperties() throws IOException {
String fileName = "debug"; // NOI18N
String file;
int i = 0;
do {
file = "nbproject/" + fileName + (i != 0 ? String.valueOf(i) : "") + ".properties"; // NOI18N
i++;
} while (helper.resolveFileObject(file) != null);
FileObject fo = FileUtil.createData(project.getProjectDirectory(), file);
FileLock lock = fo.lock();
OutputStream out = null;
InputStream in = null;
try {
out = new BufferedOutputStream(fo.getOutputStream(lock));
in = getClass().getResourceAsStream(DEBUG_PROPERTIES_TEMPLATE);
byte[] buffer = new byte[4096];
int read;
do {
read = in.read(buffer);
out.write(buffer, 0, read);
} while (read == buffer.length);
}
finally {
if (in != null)
in.close();
if (out != null)
out.close();
lock.releaseLock();
}
// set the generated properties
EditableProperties ep = helper.getProperties(file);
ProjectInformation pi = ProjectUtils.getInformation(project);
ep.setProperty(WebFreeformProperties.JPDA_SESSION_NAME, pi.getName());
ep.setProperty(WebFreeformProperties.SRC_FOLDERS, findSourceFolders(JavaProjectConstants.SOURCES_TYPE_JAVA));
ep.setProperty(WebFreeformProperties.WEB_DOCBASE_DIR, findSourceFolders(WebProjectConstants.TYPE_DOC_ROOT));
String contextPath = findContextPath();
ep.setProperty(WebFreeformProperties.CLIENT_URL, ep.getProperty(WebFreeformProperties.CLIENT_URL) + (contextPath != null ? contextPath : "/")); // NOI18N
helper.putProperties(file, ep);
return file;
}
/**
* Jump to an action binding in the editor.
* @param command an {@link ActionProvider} command name found in project.xml
*/
private void jumpToBinding(String command) {
jumpToFile(AntProjectHelper.PROJECT_XML_PATH, command, "action", "name"); // NOI18N
}
/**
* Jump to a target in the editor.
* @param scriptPath the script to open
* @param target the name of the target (in scriptPath)
*/
private void jumpToBuildScript(String scriptPath, String target) {
jumpToFile(scriptPath, target, "target", "name"); // NOI18N
}
/**
* Jump to some line in an XML file.
* @param path project-relative path to the file
* @param match {@see #findLine}
* @param elementLocalName {@see #findLine}
* @param elementAttributeName {@see #findLine}
*/
private void jumpToFile(String path, String match, String elementLocalName, String elementAttributeName) {
FileObject file = helper.getProjectDirectory().getFileObject(path);
if (file == null) {
return;
}
int line;
try {
line = findLine(file, match, elementLocalName, elementAttributeName);
} catch (IOException e) {
Logger.getLogger("global").log(Level.INFO, null, e);
return;
} catch (SAXException e) {
Logger.getLogger("global").log(Level.INFO, null, e);
return;
} catch (ParserConfigurationException e) {
Logger.getLogger("global").log(Level.INFO, null, e);
return;
}
if (line == -1) {
// Just open it.
line = 0;
}
DataObject fileDO;
try {
fileDO = DataObject.find(file);
} catch (DataObjectNotFoundException e) {
throw new AssertionError(e);
}
LineCookie lines = (LineCookie) fileDO.getCookie(LineCookie.class);
if (lines != null) {
try {
lines.getLineSet().getCurrent(line).show(ShowOpenType.OPEN, ShowVisibilityType.FOCUS);
} catch (IndexOutOfBoundsException e) {
// XXX reproducibly thrown if the document was already open. Why?? (file.refresh() above does not help.)
Logger.getLogger(WebFreeFormActionProvider.class.getName()).log(
Level.WARNING, e + " [file=" + file + " match=" + match + " line=" + line + "]"); // NOI18N
lines.getLineSet().getCurrent(0).show(ShowOpenType.OPEN, ShowVisibilityType.FOCUS);
}
}
}
private void openFile(String path) {
FileObject file = helper.getProjectDirectory().getFileObject(path);
if (file == null)
return;
DataObject fileDO;
try {
fileDO = DataObject.find(file);
}
catch (DataObjectNotFoundException e) {
throw new AssertionError(e);
}
EditCookie edit = (EditCookie)fileDO.getCookie(EditCookie.class);
if (edit != null) {
edit.edit();
}
}
/**
* Find the line number of a target in an Ant script, or some other line in an XML file.
* Able to find a certain element with a certain attribute matching a given value.
* See also AntTargetNode.TargetOpenCookie.
* @param file an Ant script or other XML file
* @param match the attribute value to match (e.g. target name)
* @param elementLocalName the (local) name of the element to look for
* @param elementAttributeName the name of the attribute to match on
* @return the line number (0-based), or -1 if not found
*/
static final int findLine(FileObject file, final String match, final String elementLocalName, final String elementAttributeName) throws IOException, SAXException, ParserConfigurationException {
InputSource in = new InputSource(file.getURL().toString());
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
SAXParser parser = factory.newSAXParser();
final int[] line = new int[] {-1};
class Handler extends DefaultHandler {
private Locator locator;
public void setDocumentLocator(Locator l) {
locator = l;
}
public void startElement(String uri, String localname, String qname, Attributes attr) throws SAXException {
if (line[0] == -1) {
if (localname.equals(elementLocalName) && match.equals(attr.getValue(elementAttributeName))) { // NOI18N
line[0] = locator.getLineNumber() - 1;
}
}
}
}
parser.parse(in, new Handler());
return line[0];
}
private String findSourceFolders(String type) {
StringBuffer result = new StringBuffer();
Element data = Util.getPrimaryConfigurationData(helper);
Element foldersEl = XMLUtil.findElement(data, "folders", Util.NAMESPACE); // NOI18N
if (foldersEl != null) {
for (Iterator i = XMLUtil.findSubElements(foldersEl).iterator(); i.hasNext();) {
Element sourceFolderEl = (Element)i.next();
Element typeEl = XMLUtil.findElement(sourceFolderEl , "type", Util.NAMESPACE); // NOI18N
if (typeEl == null || !XMLUtil.findText(typeEl).equals(type))
continue;
Element locationEl = XMLUtil.findElement(sourceFolderEl , "location", Util.NAMESPACE); // NOI18N
if (locationEl == null)
continue;
String location = XMLUtil.findText(locationEl);
if (result.length() > 0)
result.append(":"); // NOI18N
result.append(location);
}
}
return result.toString();
}
private String findContextPath() {
Element data = aux.getConfigurationFragment(WebProjectNature.EL_WEB, WebProjectNature.NS_WEB_2, true); // NOI18N
Element webModulEl = XMLUtil.findElement(data, "web-module", WebProjectNature.NS_WEB_2); // NOI18N
if (webModulEl == null)
return null;
Element contextPathEl = XMLUtil.findElement(webModulEl, "context-path", WebProjectNature.NS_WEB_2); // NOI18N
if (contextPathEl == null)
return null;
return XMLUtil.findText(contextPathEl);
}
}