1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Eclipse Public License, Version 1.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.eclipse.org/org/documents/epl-v10.php 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.ide.eclipse.adt.internal.project; 18 19 import com.android.ide.eclipse.adt.AdtConstants; 20 import com.android.sdklib.xml.AndroidManifestParser.ManifestErrorHandler; 21 22 import org.eclipse.core.resources.IFile; 23 import org.eclipse.core.resources.IMarker; 24 import org.eclipse.core.runtime.CoreException; 25 import org.eclipse.jdt.core.IJavaProject; 26 import org.xml.sax.Locator; 27 import org.xml.sax.SAXException; 28 import org.xml.sax.SAXParseException; 29 import org.xml.sax.helpers.DefaultHandler; 30 31 /** 32 * XML error handler used by the parser to report errors/warnings. 33 */ 34 public class XmlErrorHandler extends DefaultHandler implements ManifestErrorHandler { 35 36 private final IJavaProject mJavaProject; 37 /** file being parsed */ 38 private final IFile mFile; 39 /** link to the delta visitor, to set the xml error flag */ 40 private final XmlErrorListener mErrorListener; 41 42 /** 43 * Classes which implement this interface provide a method that deals 44 * with XML errors. 45 */ 46 public interface XmlErrorListener { 47 /** 48 * Sent when an XML error is detected. 49 */ errorFound()50 public void errorFound(); 51 } 52 53 public static class BasicXmlErrorListener implements XmlErrorListener { 54 public boolean mHasXmlError = false; 55 errorFound()56 public void errorFound() { 57 mHasXmlError = true; 58 } 59 } 60 XmlErrorHandler(IJavaProject javaProject, IFile file, XmlErrorListener errorListener)61 public XmlErrorHandler(IJavaProject javaProject, IFile file, XmlErrorListener errorListener) { 62 mJavaProject = javaProject; 63 mFile = file; 64 mErrorListener = errorListener; 65 } 66 XmlErrorHandler(IFile file, XmlErrorListener errorListener)67 public XmlErrorHandler(IFile file, XmlErrorListener errorListener) { 68 this(null, file, errorListener); 69 } 70 71 /** 72 * Xml Error call back 73 * @param exception the parsing exception 74 * @throws SAXException 75 */ 76 @Override error(SAXParseException exception)77 public void error(SAXParseException exception) throws SAXException { 78 handleError(exception, exception.getLineNumber()); 79 } 80 81 /** 82 * Xml Fatal Error call back 83 * @param exception the parsing exception 84 * @throws SAXException 85 */ 86 @Override fatalError(SAXParseException exception)87 public void fatalError(SAXParseException exception) throws SAXException { 88 handleError(exception, exception.getLineNumber()); 89 } 90 91 /** 92 * Xml Warning call back 93 * @param exception the parsing exception 94 * @throws SAXException 95 */ 96 @Override warning(SAXParseException exception)97 public void warning(SAXParseException exception) throws SAXException { 98 if (mFile != null) { 99 BaseProjectHelper.markResource(mFile, 100 AdtConstants.MARKER_XML, 101 exception.getMessage(), 102 exception.getLineNumber(), 103 IMarker.SEVERITY_WARNING); 104 } 105 } 106 getFile()107 protected final IFile getFile() { 108 return mFile; 109 } 110 111 /** 112 * Handles a parsing error and an optional line number. 113 * @param exception 114 * @param lineNumber 115 */ handleError(Exception exception, int lineNumber)116 public void handleError(Exception exception, int lineNumber) { 117 if (mErrorListener != null) { 118 mErrorListener.errorFound(); 119 } 120 121 String message = exception.getMessage(); 122 if (message == null) { 123 message = "Unknown error " + exception.getClass().getCanonicalName(); 124 } 125 126 if (mFile != null) { 127 BaseProjectHelper.markResource(mFile, 128 AdtConstants.MARKER_XML, 129 message, 130 lineNumber, 131 IMarker.SEVERITY_ERROR); 132 } 133 } 134 135 /** 136 * Checks that a class is valid and can be used in the Android Manifest. 137 * <p/> 138 * Errors are put as {@link IMarker} on the manifest file. 139 * @param locator 140 * @param className the fully qualified name of the class to test. 141 * @param superClassName the fully qualified name of the class it is supposed to extend. 142 * @param testVisibility if <code>true</code>, the method will check the visibility of 143 * the class or of its constructors. 144 */ checkClass(Locator locator, String className, String superClassName, boolean testVisibility)145 public void checkClass(Locator locator, String className, String superClassName, 146 boolean testVisibility) { 147 if (mJavaProject == null) { 148 return; 149 } 150 // we need to check the validity of the activity. 151 String result = BaseProjectHelper.testClassForManifest(mJavaProject, 152 className, superClassName, testVisibility); 153 if (result != BaseProjectHelper.TEST_CLASS_OK) { 154 // get the line number 155 int line = locator.getLineNumber(); 156 157 // mark the file 158 IMarker marker = BaseProjectHelper.markResource(getFile(), 159 AdtConstants.MARKER_ANDROID, result, line, IMarker.SEVERITY_ERROR); 160 161 // add custom attributes to be used by the manifest editor. 162 if (marker != null) { 163 try { 164 marker.setAttribute(AdtConstants.MARKER_ATTR_TYPE, 165 AdtConstants.MARKER_ATTR_TYPE_ACTIVITY); 166 marker.setAttribute(AdtConstants.MARKER_ATTR_CLASS, className); 167 } catch (CoreException e) { 168 } 169 } 170 } 171 } 172 } 173