refactor AndroidResourceManager

- move more common methods from xml processor implementations to resource manager
- optimize imports, reformat code
This commit is contained in:
Mikhail Mutcianko
2014-08-03 14:06:01 +04:00
committed by Yan Zhulanow
parent b5e267ed56
commit 621193681f
6 changed files with 48 additions and 39 deletions
@@ -22,6 +22,7 @@ import com.intellij.openapi.project.Project
abstract class AndroidResourceManager(val project: Project, val searchPath: String?) {
private val idPrefix = "@+id/"
abstract fun getLayoutXmlFiles(): Collection<PsiFile>
abstract fun idToXmlAttribute(id: String): PsiElement?
abstract fun renameXmlAttr(elem: PsiElement, newName: String)
@@ -29,4 +30,8 @@ abstract class AndroidResourceManager(val project: Project, val searchPath: Stri
public fun nameToId(name: String): String = idPrefix + name
public fun idToName(id: String): String = id.replace(idPrefix, "")
public fun isResourceId(str: String?): Boolean = str?.startsWith(idPrefix) ?: false
abstract fun readManifest(): AndroidManifest
inner class NoUIXMLsFound : Exception("No android UI xmls found in $searchPath")
}
@@ -19,9 +19,16 @@ package org.jetbrains.jet.lang.resolve.android
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiManager
import java.util.ArrayList
import com.intellij.openapi.vfs.VirtualFileManager
import com.intellij.psi.PsiManager
import org.jetbrains.jet.lang.resolve.android.AndroidUIXmlProcessor.NoAndroidManifestFound
import java.util.ArrayList
import java.io.File
import java.io.FileInputStream
import javax.xml.parsers.SAXParser
import javax.xml.parsers.SAXParserFactory
import org.xml.sax.helpers.DefaultHandler
import org.xml.sax.Attributes
open class AndroidResourceManagerBase(project: Project, searchPath: String?) : AndroidResourceManager(project, searchPath) {
override fun getLayoutXmlFiles(): Collection<PsiFile> {
@@ -40,4 +47,34 @@ open class AndroidResourceManagerBase(project: Project, searchPath: String?) : A
override fun renameProperty(oldName: String, newName: String) {
}
val saxParser: SAXParser = initSAX()
protected fun initSAX(): SAXParser {
val saxFactory = SAXParserFactory.newInstance()
saxFactory?.setNamespaceAware(true)
return saxFactory!!.newSAXParser()
}
override fun readManifest(): AndroidManifest {
try {
val manifestXml = File(searchPath!!).getParentFile()!!.getParentFile()!!.listFiles { it.name == "AndroidManifest.xml" }!!.first()
var _package: String = ""
try {
saxParser.parse(FileInputStream(manifestXml), object : DefaultHandler() {
override fun startElement(uri: String, localName: String, qName: String, attributes: Attributes) {
if (localName == "manifest")
_package = attributes.toMap()["package"] ?: ""
}
})
}
catch (e: Exception) {
throw e
}
return AndroidManifest(_package)
}
catch (e: Exception) {
throw NoAndroidManifestFound()
}
}
}
@@ -50,7 +50,6 @@ import com.intellij.openapi.diagnostic.Logger
abstract class AndroidUIXmlProcessor(val project: Project) {
inner class NoUIXMLsFound : Exception("No android UI xmls found in $searchPath")
class NoAndroidManifestFound : Exception("No android manifest file found in project root")
class ManifestParsingFailed
@@ -64,14 +63,6 @@ abstract class AndroidUIXmlProcessor(val project: Project) {
protected abstract val searchPath: String?
protected abstract val androidAppPackage: String
protected val saxParser: SAXParser = initSAX()
protected fun initSAX(): SAXParser {
val saxFactory = SAXParserFactory.newInstance()
saxFactory?.setNamespaceAware(true)
return saxFactory!!.newSAXParser()
}
private val fileCache = HashMap<PsiFile, String>()
private var lastCachedPsi: JetFile? = null
protected val fileModificationTime: HashMap<PsiFile, Long> = HashMap()
@@ -167,28 +158,6 @@ abstract class AndroidUIXmlProcessor(val project: Project) {
protected abstract fun lazySetup()
protected fun readManifest(): AndroidManifest {
try {
val manifestXml = File(searchPath!!).getParentFile()!!.getParentFile()!!.listFiles { it.name == "AndroidManifest.xml" }!!.first()
var _package: String = ""
try {
saxParser.parse(FileInputStream(manifestXml), object : DefaultHandler() {
override fun startElement(uri: String, localName: String, qName: String, attributes: Attributes) {
if (localName == "manifest")
_package = attributes.toMap()["package"] ?: ""
}
})
}
catch (e: Exception) {
throw e
}
return AndroidManifest(_package)
}
catch (e: Exception) {
throw NoAndroidManifestFound()
}
}
protected fun produceKotlinProperties(kw: KotlinStringWriter, ids: Collection<AndroidWidget>): StringBuffer {
for (id in ids) {
val body = arrayListOf("return findViewById(0) as ${id.className}")
@@ -24,17 +24,18 @@ class CliAndroidUIXmlProcessor(project: Project, override val searchPath: String
override var androidAppPackage: String = ""
override val resourceManager: AndroidResourceManagerBase = AndroidResourceManagerBase(project, searchPath)
override fun lazySetup() {
populateQueue()
androidAppPackage = readManifest()._package
androidAppPackage = resourceManager.readManifest()._package
}
override fun parseSingleFileImpl(file: PsiFile): String {
val ids: MutableCollection<AndroidWidget> = ArrayList()
val handler = AndroidXmlHandler({ id, wClass -> ids.add(AndroidWidget(id, wClass)) })
try {
saxParser.parse(file.getVirtualFile()?.getInputStream()!!, handler)
resourceManager.saxParser.parse(file.getVirtualFile()?.getInputStream()!!, handler)
return produceKotlinProperties(KotlinStringWriter(), ids).toString()
}
catch (e: Throwable) {
@@ -27,9 +27,6 @@ import com.intellij.psi.search.SearchScope
import com.intellij.psi.xml.XmlAttributeValue
import org.jetbrains.android.dom.wrappers.LazyValueResourceElementWrapper
import org.jetbrains.android.util.AndroidResourceUtil
import com.intellij.psi.xml.XmlFile
import com.intellij.psi.XmlElementVisitor
import com.intellij.psi.xml.XmlTag
import com.intellij.psi.xml.XmlAttribute
public class AndroidRenameProcessor : RenamePsiElementProcessor() {
@@ -32,7 +32,7 @@ class IDEAndroidUIXmlProcessor(project: Project) : AndroidUIXmlProcessor(project
override protected fun lazySetup() {
if (listenerSetUp) return
androidAppPackage = readManifest()._package
androidAppPackage = resourceManager.readManifest()._package
populateQueue()
listenerSetUp = true
}