diff options
Diffstat (limited to 'AccessCheck/src/com/android/accessibility/AccessibilityValidator.java')
-rw-r--r-- | AccessCheck/src/com/android/accessibility/AccessibilityValidator.java | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/AccessCheck/src/com/android/accessibility/AccessibilityValidator.java b/AccessCheck/src/com/android/accessibility/AccessibilityValidator.java new file mode 100644 index 0000000..5f3b031 --- /dev/null +++ b/AccessCheck/src/com/android/accessibility/AccessibilityValidator.java @@ -0,0 +1,191 @@ +/* + * Copyright 2010 Google Inc. + * + * Licensed 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 com.android.accessibility; + +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.XMLReaderFactory; + +import java.io.*; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Logger; + +/** + * An object that fetches all Android layout files and manages the testing of + * the files with the use of the AccessibilityValidationContentHandler. This + * object also reports on any errors encountered during the testing. + * + * @author dtseng@google.com (David Tseng) + */ +public class AccessibilityValidator { + /** The root path to scan for Android layout files. */ + private final File mRootFilePath; + /** Errors generated by thrown exceptions (and not by validation errors). */ + private final List<String> mGeneralErrors = new ArrayList<String>(); + /** A list of files we wish to have tested. */ + private List<InputSource> mLayoutFiles; + /** The total number of validation test errors across all files. */ + private int mTotalValidationErrors = 0; + /** The path to the Android sdk jar. */ + private final File mAndroidSdkPath; + + /** The object that handles our logging. */ + private static final Logger sLogger = Logger.getLogger("android.accessibility"); + + /** + * The entry point to this tool. + * + * @param <args> + * path on which to search for layout xml files that need + * validation + */ + public static void main(String[] args) { + sLogger.info("AccessibilityValidator"); + if (args.length == 2) { + sLogger.info("Validating classes using android jar for subclasses of ImageView"); + new AccessibilityValidator(args[0], args[1]).run(); + } else { + sLogger.info("Usage: java AccessibilityValidator <path> <Android jar path>"); + return; + } + } + + /** + * Constructs an AccessibilityValidator object using the root path and the + * android jar path. + */ + public AccessibilityValidator(String rootPath, String androidSdkPath) { + mRootFilePath = new File(rootPath); + mAndroidSdkPath = new File(androidSdkPath); + + if (!mRootFilePath.exists()) { + throw new IllegalArgumentException("Invalid root path specified " + + rootPath); + } else if (!mAndroidSdkPath.exists()) { + throw new IllegalArgumentException( + "Invalid android sdk path specified " + androidSdkPath); + } + } + + /** + * Performs validation of Android layout files and logs errors that have + * been encountered during the validation. Returns true if the validation + * passes. + */ + private boolean run() { + sLogger.info("Validating files under " + mRootFilePath); + mLayoutFiles = findLayoutFiles(mRootFilePath); + validateFiles(); + for (String error : mGeneralErrors) { + sLogger.info(error); + } + sLogger.info("done with validation"); + return mGeneralErrors.size() == 0; + } + + /** + * Accumulates a list of files under the path that meet two constraints. + * Firstly, it has a containing (parent) directory of "layout". Secondly, it + * has an xml extension + */ + private List<InputSource> findLayoutFiles(File directory) { + List<InputSource> layoutFiles = new ArrayList<InputSource>(); + + for (File file : directory.listFiles()) { + // The file is a directory; recurse on the file. + if (file.isDirectory()) { + List<InputSource> directoryFiles = findLayoutFiles(file); + layoutFiles.addAll(directoryFiles); + // Does the containing directory and filename meet our + // constraints? + } else if (directory.getName().toLowerCase().contains("layout") + && file.getName().toLowerCase().endsWith(".xml")) { + InputSource addition; + try { + addition = new InputSource(new FileReader(file)); + // Store this explicitly for logging. + addition.setPublicId(file.toString()); + layoutFiles.add(addition); + } catch (FileNotFoundException fileNotFoundException) { + mGeneralErrors.add("File not found " + + fileNotFoundException); + } + } + } + + return layoutFiles; + } + + /* + * Processes a list of files via an AccessibilityValidationContentHandler. + * The caller will only be notified of errors via logging. + */ + public void validateFiles() { + sLogger.info("Validating " + getLayoutFiles().size()); + XMLReader reader; + try { + reader = XMLReaderFactory.createXMLReader(); + } catch (SAXException saxExp) { + mGeneralErrors.add("Error " + saxExp); + return; + } + for (InputSource file : getLayoutFiles()) { + try { + AccessibilityValidationContentHandler contentHandler + = new AccessibilityValidationContentHandler( + file.getPublicId(), mAndroidSdkPath); + reader.setContentHandler(contentHandler); + reader.parse(file); + mTotalValidationErrors += contentHandler.getValidationErrors(); + } catch (IOException ioExp) { + mGeneralErrors.add("Error reading file " + ioExp); + } catch (SAXException saxExp) { + mGeneralErrors.add("Error " + saxExp); + } + } + } + + /** + * Returns the number of general errors (considered caught exceptions). + */ + public List<String> getGeneralErrors() { + return mGeneralErrors; + } + + /** + * Sets the files to be tested. + */ + public void setLayoutFiles(List<InputSource> layoutFiles) { + this.mLayoutFiles = layoutFiles; + } + + /** + * Gets the files to be tested. + */ + public List<InputSource> getLayoutFiles() { + return mLayoutFiles; + } + + /** + * Gets the total number of test validation errors across all files. + */ + public int getTotalValidationErrors() { + return mTotalValidationErrors; + } +} |