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.common.xml.AndroidManifestParser.ManifestErrorHandler; 20 import com.android.ide.eclipse.adt.AdtConstants; 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 */ 50 public void errorFound(); 51 } 52 53 public static class BasicXmlErrorListener implements XmlErrorListener { 54 public boolean mHasXmlError = false; 55 56 @Override 57 public void errorFound() { 58 mHasXmlError = true; 59 } 60 } 61 62 public XmlErrorHandler(IJavaProject javaProject, IFile file, XmlErrorListener errorListener) { 63 mJavaProject = javaProject; 64 mFile = file; 65 mErrorListener = errorListener; 66 } 67 68 public XmlErrorHandler(IFile file, XmlErrorListener errorListener) { 69 this(null, file, errorListener); 70 } 71 72 /** 73 * Xml Error call back 74 * @param exception the parsing exception 75 * @throws SAXException 76 */ 77 @Override 78 public void error(SAXParseException exception) throws SAXException { 79 handleError(exception, exception.getLineNumber()); 80 } 81 82 /** 83 * Xml Fatal Error call back 84 * @param exception the parsing exception 85 * @throws SAXException 86 */ 87 @Override 88 public void fatalError(SAXParseException exception) throws SAXException { 89 handleError(exception, exception.getLineNumber()); 90 } 91 92 /** 93 * Xml Warning call back 94 * @param exception the parsing exception 95 * @throws SAXException 96 */ 97 @Override 98 public void warning(SAXParseException exception) throws SAXException { 99 if (mFile != null) { 100 BaseProjectHelper.markResource(mFile, 101 AdtConstants.MARKER_XML, 102 exception.getMessage(), 103 exception.getLineNumber(), 104 IMarker.SEVERITY_WARNING); 105 } 106 } 107 108 protected final IFile getFile() { 109 return mFile; 110 } 111 112 /** 113 * Handles a parsing error and an optional line number. 114 * @param exception 115 * @param lineNumber 116 */ 117 @Override 118 public void handleError(Exception exception, int lineNumber) { 119 if (mErrorListener != null) { 120 mErrorListener.errorFound(); 121 } 122 123 String message = exception.getMessage(); 124 if (message == null) { 125 message = "Unknown error " + exception.getClass().getCanonicalName(); 126 } 127 128 if (mFile != null) { 129 BaseProjectHelper.markResource(mFile, 130 AdtConstants.MARKER_XML, 131 message, 132 lineNumber, 133 IMarker.SEVERITY_ERROR); 134 } 135 } 136 137 /** 138 * Checks that a class is valid and can be used in the Android Manifest. 139 * <p/> 140 * Errors are put as {@link IMarker} on the manifest file. 141 * @param locator 142 * @param className the fully qualified name of the class to test. 143 * @param superClassName the fully qualified name of the class it is supposed to extend. 144 * @param testVisibility if <code>true</code>, the method will check the visibility of 145 * the class or of its constructors. 146 */ 147 @Override 148 public void checkClass(Locator locator, String className, String superClassName, 149 boolean testVisibility) { 150 if (mJavaProject == null) { 151 return; 152 } 153 // we need to check the validity of the activity. 154 String result = BaseProjectHelper.testClassForManifest(mJavaProject, 155 className, superClassName, testVisibility); 156 if (result != BaseProjectHelper.TEST_CLASS_OK) { 157 // get the line number 158 int line = locator.getLineNumber(); 159 160 // mark the file 161 IMarker marker = BaseProjectHelper.markResource(getFile(), 162 AdtConstants.MARKER_ANDROID, result, line, IMarker.SEVERITY_ERROR); 163 164 // add custom attributes to be used by the manifest editor. 165 if (marker != null) { 166 try { 167 marker.setAttribute(AdtConstants.MARKER_ATTR_TYPE, 168 AdtConstants.MARKER_ATTR_TYPE_ACTIVITY); 169 marker.setAttribute(AdtConstants.MARKER_ATTR_CLASS, className); 170 } catch (CoreException e) { 171 } 172 } 173 } 174 } 175 } 176