BaseBuilderpublic abstract class BaseBuilder extends org.eclipse.core.resources.IncrementalProjectBuilder Base builder for XML files. This class allows for basic XML parsing with
error checking and marking the files for errors/warnings. |
Fields Summary |
---|
private static final Pattern | sPattern0Line1Single line aapt warning for skipping files.
" (skipping hidden file '<file path>'" | private static final Pattern | sPattern1Line1First line of dual line aapt error.
"ERROR at line <line>: <error>"
" (Occurred while parsing <path>)" | private static final Pattern | sPattern1Line2Second line of dual line aapt error.
"ERROR at line <line>: <error>"
" (Occurred while parsing <path>)"
| private static final Pattern | sPattern2Line1First line of dual line aapt error.
"ERROR: <error>"
"Defined at file <path> line <line>" | private static final Pattern | sPattern2Line2Second line of dual line aapt error.
"ERROR: <error>"
"Defined at file <path> line <line>"
| private static final Pattern | sPattern3Line1Single line aapt error
"<path> line <line>: <error>" | private static final Pattern | sPattern4Line1First line of dual line aapt error.
"ERROR parsing XML file <path>"
"<error> at line <line>" | private static final Pattern | sPattern4Line2Second line of dual line aapt error.
"ERROR parsing XML file <path>"
"<error> at line <line>"
| private static final Pattern | sPattern5Line1Single line aapt warning
"<path>:<line>: <error>" | private static final Pattern | sPattern6Line1Single line aapt error
"<path>:<line>: <error>" | private static final Pattern | sPattern7Line14 line aapt error
"ERROR: 9-path image <path> malformed"
Line 2 and 3 are taken as-is while line 4 is ignored (it repeats with
'ERROR: failure processing <path>) | private static final Pattern | sPattern8Line1 | private static final Pattern | sPattern9Line12 line aapt error
"ERROR: Invalid configuration: foo"
" ^^^"
There's no need to parse the 2nd line. | private SAXParserFactory | mParserFactorySAX Parser factory. |
Constructors Summary |
---|
public BaseBuilder()
super();
mParserFactory = SAXParserFactory.newInstance();
// FIXME when the compiled XML support for namespace is in, set this to true.
mParserFactory.setNamespaceAware(false);
|
Methods Summary |
---|
protected final void | abortOnBadSetup(org.eclipse.core.resources.IProject project)Aborts the build if the SDK/project setups are broken. This does not
display any errors.
// check if we have finished loading the SDK.
if (AdtPlugin.getDefault().getSdkLoadStatus() != LoadStatus.LOADED) {
// we exit silently
stopBuild("SDK is not loaded yet");
}
// abort if there are TARGET or ADT type markers
IMarker[] markers = project.findMarkers(AdtConstants.MARKER_TARGET,
false /*includeSubtypes*/, IResource.DEPTH_ZERO);
if (markers.length > 0) {
stopBuild("");
}
markers = project.findMarkers(AdtConstants.MARKER_ADT, false /*includeSubtypes*/,
IResource.DEPTH_ZERO);
if (markers.length > 0) {
stopBuild("");
}
| private final boolean | checkAndMark(java.lang.String location, java.lang.String lineStr, java.lang.String message, java.lang.String root, org.eclipse.core.resources.IProject project, java.lang.String markerId, int severity)Check if the parameters gotten from the error output are valid, and mark
the file with an AAPT marker.
// check this is in fact a file
if (location != null) {
File f = new File(location);
if (f.exists() == false) {
return false;
}
}
// get the line number
int line = -1; // default value for error with no line.
if (lineStr != null) {
try {
line = Integer.parseInt(lineStr);
} catch (NumberFormatException e) {
// looks like the string we extracted wasn't a valid
// file number. Parsing failed and we return true
return false;
}
}
// add the marker
IResource f2 = project;
if (location != null) {
f2 = getResourceFromFullPath(location, root, project);
if (f2 == null) {
return false;
}
}
// check if there's a similar marker already, since aapt is launched twice
boolean markerAlreadyExists = false;
try {
IMarker[] markers = f2.findMarkers(markerId, true, IResource.DEPTH_ZERO);
for (IMarker marker : markers) {
int tmpLine = marker.getAttribute(IMarker.LINE_NUMBER, -1);
if (tmpLine != line) {
break;
}
int tmpSeverity = marker.getAttribute(IMarker.SEVERITY, -1);
if (tmpSeverity != severity) {
break;
}
String tmpMsg = marker.getAttribute(IMarker.MESSAGE, null);
if (tmpMsg == null || tmpMsg.equals(message) == false) {
break;
}
// if we're here, all the marker attributes are equals, we found it
// and exit
markerAlreadyExists = true;
break;
}
} catch (CoreException e) {
// if we couldn't get the markers, then we just mark the file again
// (since markerAlreadyExists is initialized to false, we do nothing)
}
if (markerAlreadyExists == false) {
if (line != -1) {
BaseProjectHelper.addMarker(f2, markerId, message, line,
severity);
} else {
BaseProjectHelper.addMarker(f2, markerId, message, severity);
}
}
return true;
| protected final void | checkXML(org.eclipse.core.resources.IResource resource, com.android.ide.eclipse.adt.build.BaseBuilder$BaseDeltaVisitor visitor)Checks an Xml file for validity. Errors/warnings will be marked on the
file
// first make sure this is an xml file
if (resource instanceof IFile) {
IFile file = (IFile)resource;
// remove previous markers
removeMarkersFromFile(file, AndroidConstants.MARKER_XML);
// create the error handler
XmlErrorHandler reporter = new XmlErrorHandler(file, visitor);
try {
// parse
getParser().parse(file.getContents(), reporter);
} catch (Exception e1) {
}
}
| protected final java.lang.String[] | getExternalJars()Returns an array of external jar files used by the project.
// get the current project
IProject project = getProject();
// get a java project from it
IJavaProject javaProject = JavaCore.create(project);
IWorkspaceRoot wsRoot = ResourcesPlugin.getWorkspace().getRoot();
ArrayList<String> oslibraryList = new ArrayList<String>();
IClasspathEntry[] classpaths = javaProject.readRawClasspath();
if (classpaths != null) {
for (IClasspathEntry e : classpaths) {
if (e.getEntryKind() == IClasspathEntry.CPE_LIBRARY ||
e.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
// if this is a classpath variable reference, we resolve it.
if (e.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
e = JavaCore.getResolvedClasspathEntry(e);
}
// get the IPath
IPath path = e.getPath();
// check the name ends with .jar
if (AndroidConstants.EXT_JAR.equalsIgnoreCase(path.getFileExtension())) {
boolean local = false;
IResource resource = wsRoot.findMember(path);
if (resource != null && resource.exists() &&
resource.getType() == IResource.FILE) {
local = true;
oslibraryList.add(resource.getLocation().toOSString());
}
if (local == false) {
// if the jar path doesn't match a workspace resource,
// then we get an OSString and check if this links to a valid file.
String osFullPath = path.toOSString();
File f = new File(osFullPath);
if (f.exists()) {
oslibraryList.add(osFullPath);
} else {
String message = String.format( Messages.Couldnt_Locate_s_Error,
path);
AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE,
project, message);
// Also put a warning marker on the project
markProject(AdtConstants.MARKER_ADT, message,
IMarker.SEVERITY_WARNING);
}
}
}
}
}
}
return oslibraryList.toArray(new String[oslibraryList.size()]);
| private final java.util.regex.Matcher | getNextLineMatcher(java.util.ArrayList lines, int nextIndex, java.util.regex.Pattern pattern)Returns a matching matcher for the next line
// unless we can't, because we reached the last line
if (nextIndex == lines.size()) {
// we expected a 2nd line, so we flag as error
// and we bail
return null;
}
Matcher m = pattern.matcher(lines.get(nextIndex));
if (m.matches()) {
return m;
}
return null;
| protected final javax.xml.parsers.SAXParser | getParser()Returns the SAXParserFactory, instantiating it first if it's not already
created.
return mParserFactory.newSAXParser();
| private org.eclipse.core.resources.IResource | getResourceFromFullPath(java.lang.String filename, java.lang.String root, org.eclipse.core.resources.IProject project)
if (filename.startsWith(root)) {
String file = filename.substring(root.length());
// get the resource
IResource r = project.findMember(file);
// if the resource is valid, we add the marker
if (r.exists()) {
return r;
}
}
return null;
| protected final int | grabProcessOutput(java.lang.Process process, java.util.ArrayList results)Get the stderr output of a process and return when the process is done.
// Due to the limited buffer size on windows for the standard io (stderr, stdout), we
// *need* to read both stdout and stderr all the time. If we don't and a process output
// a large amount, this could deadlock the process.
// read the lines as they come. if null is returned, it's
// because the process finished
new Thread("") { //$NON-NLS-1$
@Override
public void run() {
// create a buffer to read the stderr output
InputStreamReader is = new InputStreamReader(process.getErrorStream());
BufferedReader errReader = new BufferedReader(is);
try {
while (true) {
String line = errReader.readLine();
if (line != null) {
results.add(line);
} else {
break;
}
}
} catch (IOException e) {
// do nothing.
}
}
}.start();
new Thread("") { //$NON-NLS-1$
@Override
public void run() {
InputStreamReader is = new InputStreamReader(process.getInputStream());
BufferedReader outReader = new BufferedReader(is);
IProject project = getProject();
try {
while (true) {
String line = outReader.readLine();
if (line != null) {
AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE,
project, line);
} else {
break;
}
}
} catch (IOException e) {
// do nothing.
}
}
}.start();
// get the return code from the process
return process.waitFor();
| protected boolean | loadProjectBooleanProperty(java.lang.String propertyName, boolean defaultValue)Loads a boolean property from the persistent storage of the project.
IProject project = getProject();
return ProjectHelper.loadBooleanProperty(project, propertyName, defaultValue);
| protected org.eclipse.core.resources.IResource | loadProjectResourceProperty(java.lang.String propertyName)Loads the path of a resource from the persistent storage of the project, and returns the
corresponding IResource object.
IProject project = getProject();
return ProjectHelper.loadResourceProperty(project, propertyName);
| protected java.lang.String | loadProjectStringProperty(java.lang.String propertyName)Loads a String property from the persistent storage of the project.
IProject project = getProject();
return ProjectHelper.loadStringProperty(project, propertyName);
| protected final void | markProject(java.lang.String markerId, java.lang.String message, int severity)Adds a marker to the current project.
BaseProjectHelper.addMarker(getProject(), markerId, message, severity);
| protected final boolean | parseAaptOutput(java.util.ArrayList results, org.eclipse.core.resources.IProject project)Parse the output of aapt and mark the incorrect file with error markers
// nothing to parse? just return false;
if (results.size() == 0) {
return false;
}
// get the root of the project so that we can make IFile from full
// file path
String osRoot = project.getLocation().toOSString();
Matcher m;
for (int i = 0; i < results.size(); i++) {
String p = results.get(i);
m = sPattern0Line1.matcher(p);
if (m.matches()) {
// we ignore those (as this is an ignore message from aapt)
continue;
}
m = sPattern1Line1.matcher(p);
if (m.matches()) {
String lineStr = m.group(1);
String msg = m.group(2);
// get the matcher for the next line.
m = getNextLineMatcher(results, ++i, sPattern1Line2);
if (m == null) {
return true;
}
String location = m.group(1);
// check the values and attempt to mark the file.
if (checkAndMark(location, lineStr, msg, osRoot, project,
AndroidConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) {
return true;
}
continue;
}
// this needs to be tested before Pattern2 since they both start with 'ERROR:'
m = sPattern7Line1.matcher(p);
if (m.matches()) {
String location = m.group(1);
String msg = p; // default msg is the line in case we don't find anything else
if (++i < results.size()) {
msg = results.get(i).trim();
if (++i < results.size()) {
msg = msg + " - " + results.get(i).trim(); //$NON-NLS-1$
// skip the next line
i++;
}
}
// display the error
if (checkAndMark(location, null, msg, osRoot, project,
AndroidConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) {
return true;
}
// success, go to the next line
continue;
}
m = sPattern2Line1.matcher(p);
if (m.matches()) {
// get the msg
String msg = m.group(1);
// get the matcher for the next line.
m = getNextLineMatcher(results, ++i, sPattern2Line2);
if (m == null) {
return true;
}
String location = m.group(1);
String lineStr = m.group(2);
// check the values and attempt to mark the file.
if (checkAndMark(location, lineStr, msg, osRoot, project,
AndroidConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) {
return true;
}
continue;
}
m = sPattern3Line1.matcher(p);
if (m.matches()) {
String location = m.group(1);
String lineStr = m.group(2);
String msg = m.group(3);
// check the values and attempt to mark the file.
if (checkAndMark(location, lineStr, msg, osRoot, project,
AndroidConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) {
return true;
}
// success, go to the next line
continue;
}
m = sPattern4Line1.matcher(p);
if (m.matches()) {
// get the filename.
String location = m.group(1);
// get the matcher for the next line.
m = getNextLineMatcher(results, ++i, sPattern4Line2);
if (m == null) {
return true;
}
String msg = m.group(1);
String lineStr = m.group(2);
// check the values and attempt to mark the file.
if (checkAndMark(location, lineStr, msg, osRoot, project,
AndroidConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) {
return true;
}
// success, go to the next line
continue;
}
m = sPattern5Line1.matcher(p);
if (m.matches()) {
String location = m.group(1);
String lineStr = m.group(2);
String msg = m.group(3);
// check the values and attempt to mark the file.
if (checkAndMark(location, lineStr, msg, osRoot, project,
AndroidConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_WARNING) == false) {
return true;
}
// success, go to the next line
continue;
}
m = sPattern6Line1.matcher(p);
if (m.matches()) {
String location = m.group(1);
String lineStr = m.group(2);
String msg = m.group(3);
// check the values and attempt to mark the file.
if (checkAndMark(location, lineStr, msg, osRoot, project,
AndroidConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) {
return true;
}
// success, go to the next line
continue;
}
m = sPattern8Line1.matcher(p);
if (m.matches()) {
String location = m.group(2);
String msg = m.group(1);
// check the values and attempt to mark the file.
if (checkAndMark(location, null, msg, osRoot, project,
AndroidConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) {
return true;
}
// success, go to the next line
continue;
}
m = sPattern9Line1.matcher(p);
if (m.matches()) {
String badConfig = m.group(1);
String msg = String.format("APK Configuration filter '%1$s' is invalid", badConfig);
// skip the next line
i++;
// check the values and attempt to mark the file.
if (checkAndMark(null /*location*/, null, msg, osRoot, project,
AndroidConstants.MARKER_AAPT_PACKAGE, IMarker.SEVERITY_ERROR) == false) {
return true;
}
// success, go to the next line
continue;
}
// invalid line format, flag as error, and bail
return true;
}
return false;
| protected void | removeDerivedResources(org.eclipse.core.resources.IResource resource, org.eclipse.core.runtime.IProgressMonitor monitor)Recursively delete all the derived resources.
if (resource.exists()) {
if (resource.isDerived()) {
resource.delete(true, new SubProgressMonitor(monitor, 10));
} else if (resource.getType() == IResource.FOLDER) {
IFolder folder = (IFolder)resource;
IResource[] members = folder.members();
for (IResource member : members) {
removeDerivedResources(member, monitor);
}
}
}
| protected final void | removeMarkersFromContainer(org.eclipse.core.resources.IContainer folder, java.lang.String markerId)Removes markers from a container and its children.
try {
if (folder.exists()) {
folder.deleteMarkers(markerId, true, IResource.DEPTH_INFINITE);
}
} catch (CoreException ce) {
String msg = String.format(Messages.Marker_Delete_Error, markerId, folder.toString());
AdtPlugin.printErrorToConsole(getProject(), msg);
}
| protected final void | removeMarkersFromFile(org.eclipse.core.resources.IFile file, java.lang.String markerId)Removes markers from a file.
try {
if (file.exists()) {
file.deleteMarkers(markerId, true, IResource.DEPTH_ZERO);
}
} catch (CoreException ce) {
String msg = String.format(Messages.Marker_Delete_Error, markerId, file.toString());
AdtPlugin.printErrorToConsole(getProject(), msg);
}
| protected static final void | removeMarkersFromProject(org.eclipse.core.resources.IProject project, java.lang.String markerId)Removes markers from a project and its children.
try {
if (project.exists()) {
project.deleteMarkers(markerId, true, IResource.DEPTH_INFINITE);
}
} catch (CoreException ce) {
String msg = String.format(Messages.Marker_Delete_Error, markerId, project.getName());
AdtPlugin.printErrorToConsole(project, msg);
}
| protected boolean | saveProjectBooleanProperty(java.lang.String propertyName, boolean value)Saves a property into the persistent storage of the project.
IProject project = getProject();
return ProjectHelper.saveStringProperty(project, propertyName, Boolean.toString(value));
| protected boolean | saveProjectResourceProperty(java.lang.String propertyName, org.eclipse.core.resources.IResource resource)Saves the path of a resource into the persistent storate of the project.
return ProjectHelper.saveResourceProperty(getProject(), propertyName, resource);
| protected boolean | saveProjectStringProperty(java.lang.String propertyName, java.lang.String value)Saves a String property into the persistent storage of the project.
IProject project = getProject();
return ProjectHelper.saveStringProperty(project, propertyName, value);
| protected final void | stopBuild(java.lang.String error, java.lang.Object args)Throws an exception to cancel the build.
throw new CoreException(new Status(IStatus.CANCEL, AdtPlugin.PLUGIN_ID,
String.format(error, args)));
|
|