diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml index eab1d2f..60f773d 100644 --- a/META-INF/plugin.xml +++ b/META-INF/plugin.xml @@ -1,7 +1,7 @@ jp.funnything.offing_harbor Android Layout ID Converter - 1.3 + 1.4 Yosaku Toyama ' tag 1.3: Always specify resource id if ButterKnife selected.
1.2: Fix bugs.
1.1: Add ButterKnife support. Add java visibility support. (@zaki50++)
@@ -44,7 +45,7 @@ - + diff --git a/src/ConvertAction.java b/src/ConvertAction.java index bb6ce8b..c4375ca 100644 --- a/src/ConvertAction.java +++ b/src/ConvertAction.java @@ -42,7 +42,7 @@ public void actionPerformed(AnActionEvent e) { return; } - VirtualFile layoutFile = traverseLayoutFileByName(name, e.getProject().getBaseDir(), file, null); + VirtualFile layoutFile = ConvertUtils.traverseLayoutFileByName(name, e.getProject().getBaseDir(), file, null); if (layoutFile == null) { showError(String.format("Cannot find layout file for name [%s]", name)); @@ -76,42 +76,7 @@ private String extractLayoutFileNameFromJavaFile(VirtualFile file) { } } - /** - * 基準ファイルから子を優先して探索する - */ - private VirtualFile traverseLayoutFileByName(String name, VirtualFile baseDir, VirtualFile file, VirtualFile traverseFrom) { - VirtualFile parent = file.getParent(); - - if (!file.isDirectory() && file.getName().equalsIgnoreCase(name + ".xml")) { - if (parent != null && parent.getName().startsWith("layout")) { - VirtualFile grandParent = parent.getParent(); - if (grandParent != null && grandParent.getName().equalsIgnoreCase("res")) { - return file; - } - } - } - - String traverseFromUrl = traverseFrom != null ? traverseFrom.getUrl() : null; - for (VirtualFile child : file.getChildren()) { - if (!child.getUrl().equals(traverseFromUrl) && !child.getName().startsWith(".")) { - VirtualFile layoutFile = traverseLayoutFileByName(name, baseDir, child, file); - if (layoutFile != null) { - return layoutFile; - } - } - } - - if (!file.getUrl().equals(baseDir.getUrl())) { - if (parent != null) { - if (!parent.getUrl().equals(traverseFromUrl)) { - return traverseLayoutFileByName(name, baseDir, parent, file); - } - } - } - - return null; - } private void showError(String content) { Notifications.Bus.notify(new Notification("OffingHarbor", "OffingHarbor", content, NotificationType.ERROR)); diff --git a/src/ConvertConfig.java b/src/ConvertConfig.java index 018eadd..dc918b4 100644 --- a/src/ConvertConfig.java +++ b/src/ConvertConfig.java @@ -23,6 +23,7 @@ public enum Visibility { public ConvertFormat format; public Visibility visibility; public boolean useSmartType; + public boolean detectIncludeNode; public ConvertConfig() { // default values @@ -31,6 +32,7 @@ public ConvertConfig() { format = ConvertFormat.PLAIN; visibility = Visibility.PRIVATE; useSmartType = false; + detectIncludeNode = true; } } diff --git a/src/ConvertConfigDialog.java b/src/ConvertConfigDialog.java index 01004fc..ba0b1d2 100644 --- a/src/ConvertConfigDialog.java +++ b/src/ConvertConfigDialog.java @@ -27,6 +27,7 @@ public class ConvertConfigDialog extends DialogWrapper { private JRadioButton mVisibilityPackagePrivate; private JRadioButton mVisibilityProtected; private JCheckBox mSmartTypeCheckBox; + private JCheckBox mIncludeNodeCheckBox; public ConvertConfigDialog(Project project, VirtualFile layoutFile) { super(project, true); @@ -141,6 +142,10 @@ public void actionPerformed(ActionEvent actionEvent) { mSmartTypeCheckBox = new JCheckBox("Detect Type by ID"); smartTypeBox.add(mSmartTypeCheckBox); + mIncludeNodeCheckBox = new JCheckBox("Detect 'include' tag"); + mIncludeNodeCheckBox.setSelected(true); + smartTypeBox.add(mIncludeNodeCheckBox); + box.add(Box.createHorizontalStrut(5)); box.add(smartTypeBox); @@ -155,6 +160,7 @@ private ConvertConfig getConfig() { config.format = getFormat(); config.visibility = getVisibility(); config.useSmartType = mSmartTypeCheckBox.isSelected(); + config.detectIncludeNode = mIncludeNodeCheckBox.isSelected(); return config; } diff --git a/src/ConvertExecutor.java b/src/ConvertExecutor.java index e6bb3b7..ddd5be1 100644 --- a/src/ConvertExecutor.java +++ b/src/ConvertExecutor.java @@ -16,6 +16,7 @@ import org.w3c.dom.NodeList; import org.xml.sax.SAXException; +import javax.help.search.ConfigFile; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import java.awt.datatransfer.StringSelection; @@ -133,17 +134,14 @@ private Tree(String name) { } } + private ConvertConfig mConfig; + private Project mProject; + public void execute(Project project, VirtualFile file, ConvertConfig config) { List infos; - InputStream is = null; - try { - is = file.getInputStream(); - infos = extractViewInfos(is); - } catch (IOException e) { - throw new RuntimeException(e); - } finally { - Util.closeQuietly(is); - } + mProject = project; + mConfig = config; + infos = extractViewInfos(file); Tree viewNameTree = config.useSmartType ? prepareViewNames(project) : null; String javaCode = generateJavaCode(infos, viewNameTree, config); @@ -154,41 +152,64 @@ public void execute(Project project, VirtualFile file, ConvertConfig config) { Notifications.Bus.notify(new Notification("OffingHarbor", "OffingHarbor", "Code is copied to clipboard", NotificationType.INFORMATION), project); } - private List extractViewInfos(InputStream is) { + private List extractViewInfos(VirtualFile file) { + List infos; + InputStream is = null; + try { - return traverseViewInfos(DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is)); + is = file.getInputStream(); + return traverseViewInfos(file ,DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is)); } catch (ParserConfigurationException e) { throw new RuntimeException(e); } catch (SAXException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); + } finally { + Util.closeQuietly(is); } } - private List traverseViewInfos(Node node) { + private List traverseViewInfos(VirtualFile file, Node node) { List infos = Lists.newArrayList(); if (node.getNodeType() == Node.ELEMENT_NODE) { - Node idNode = node.getAttributes().getNamedItem("android:id"); - - if (idNode != null) { - String value = idNode.getNodeValue(); - String[] values = value.split("/"); - - if (values.length != 2) { - throw new IllegalStateException("android:id value is invalid"); + String[] elements = node.getNodeName().split("\\."); + String type = elements[elements.length-1]; + + if ("include".equals(type) && mConfig.detectIncludeNode) { + Node layoutNode = node.getAttributes().getNamedItem("layout"); + if(layoutNode != null){ + String value = layoutNode.getNodeValue(); + String[] values = value.split("/"); + + if (values.length != 2) { + throw new IllegalStateException("layout value is invalid"); + } + VirtualFile layoutFile = ConvertUtils.traverseLayoutFileByName(values[1], mProject.getBaseDir(), file, null); + if (layoutFile != null) { + infos.addAll(extractViewInfos(layoutFile)); + } } + } else { + Node idNode = node.getAttributes().getNamedItem("android:id"); - String[] elements = node.getNodeName().split("\\."); + if (idNode != null) { + String value = idNode.getNodeValue(); + String[] values = value.split("/"); - infos.add(new AndroidViewInfo(elements[elements.length - 1], values[1])); + if (values.length != 2) { + throw new IllegalStateException("android:id value is invalid"); + } + + infos.add(new AndroidViewInfo(elements[elements.length - 1], values[1])); + } } } NodeList children = node.getChildNodes(); for (int index = 0; index < children.getLength(); index++) { - infos.addAll(traverseViewInfos(children.item(index))); + infos.addAll(traverseViewInfos(file, children.item(index))); } return infos; diff --git a/src/ConvertUtils.java b/src/ConvertUtils.java new file mode 100644 index 0000000..0f8e3df --- /dev/null +++ b/src/ConvertUtils.java @@ -0,0 +1,43 @@ +import com.intellij.openapi.vfs.VirtualFile; + +/** + * Created by zhouzhiyong on 15-7-24. + */ +public class ConvertUtils { + /** + * 基準ファイルから子を優先して探索する + */ + public static VirtualFile traverseLayoutFileByName(String name, VirtualFile baseDir, VirtualFile file, VirtualFile traverseFrom) { + VirtualFile parent = file.getParent(); + + if (!file.isDirectory() && file.getName().equalsIgnoreCase(name + ".xml")) { + if (parent != null && parent.getName().startsWith("layout")) { + VirtualFile grandParent = parent.getParent(); + if (grandParent != null && grandParent.getName().equalsIgnoreCase("res")) { + return file; + } + } + } + + String traverseFromUrl = traverseFrom != null ? traverseFrom.getUrl() : null; + + for (VirtualFile child : file.getChildren()) { + if (!child.getUrl().equals(traverseFromUrl) && !child.getName().startsWith(".")) { + VirtualFile layoutFile = traverseLayoutFileByName(name, baseDir, child, file); + if (layoutFile != null) { + return layoutFile; + } + } + } + + if (!file.getUrl().equals(baseDir.getUrl())) { + if (parent != null) { + if (!parent.getUrl().equals(traverseFromUrl)) { + return traverseLayoutFileByName(name, baseDir, parent, file); + } + } + } + + return null; + } +}