OSDN Git Service

Binary XML editor
authorsnpe <snpe@snpe.rs>
Sat, 22 Jan 2011 03:15:08 +0000 (04:15 +0100)
committersnpe <snpe@snpe.rs>
Wed, 2 Feb 2011 23:47:03 +0000 (00:47 +0100)
The change enable to review xml files from the android.jar file.
It works so that actually open file from
<SDK_HOME>/android-<APILEVEL>/data.
The com.android.ide.eclipse.adt.binaryXml (BinaryXMLDescriber)
content type associates Android resource xml files to the
BinaryXMLMultiPageEditorPart editor.
The editor checks if the file is contained in jar and is so,
convert editor input to XmlStorageEditorInput that handles
corresponding file from Android SDK.

Change-Id: I8596f0d3ca5477a12dc25f551243f125f8e6ba7e

eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/binaryxml/BinaryXMLDescriber.java [new file with mode: 0644]
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/binaryxml/BinaryXMLMultiPageEditorPart.java [new file with mode: 0644]
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/binaryxml/FileStorage.java [new file with mode: 0644]
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/binaryxml/XmlStorageEditorInput.java [new file with mode: 0644]

index ce54cac..551e6be 100644 (file)
             commandId="com.android.ide.eclipse.adt.launch.LaunchShortcut.run"
             schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"/>
    </extension>
+   <extension point="org.eclipse.core.contenttype.contentTypes">
+    <content-type id="com.android.ide.eclipse.adt.binaryXml" name="Android Binary XML"
+        priority="high"
+        file-extensions="xml">
+        <describer
+            class="com.android.ide.eclipse.adt.internal.editors.binaryxml.BinaryXMLDescriber">
+        </describer>
+    </content-type>
+  </extension>
+  <extension point="org.eclipse.ui.editors">
+        <editor
+            name="Android Binary XML editor"
+            icon="$nl$/icons/android_file.png"
+            contributorClass="org.eclipse.wst.xml.ui.internal.tabletree.XMLMultiPageEditorActionBarContributor"
+            class="com.android.ide.eclipse.adt.internal.editors.binaryxml.BinaryXMLMultiPageEditorPart"
+            symbolicFontName="org.eclipse.wst.sse.ui.textfont"
+            id="com.android.ide.eclipse.adt.binedit.BinaryXMLMultiPageEditorPart">
+            <contentTypeBinding
+                contentTypeId="com.android.ide.eclipse.adt.binaryXml" />
+        </editor>
+    </extension>
 </plugin>
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/binaryxml/BinaryXMLDescriber.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/binaryxml/BinaryXMLDescriber.java
new file mode 100644 (file)
index 0000000..846eb44
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
+ *
+ * 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.ide.eclipse.adt.internal.editors.binaryxml;
+
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.core.runtime.content.IContentDescriber;
+import org.eclipse.core.runtime.content.IContentDescription;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * A content describer for Android binary xml files
+ *
+ * <p>
+ * This class referenced by the "describer" configuration element in
+ * extensions to the <code>org.eclipse.core.runtime.contentTypes</code>
+ * extension point.
+ * </p>
+ *
+ * References :
+ * <a>http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;
+ * f=include/utils/ResourceTypes.h</a>
+ *
+ */
+public class BinaryXMLDescriber implements IContentDescriber {
+
+    private static final int RES_XML_HEADER_SIZE = 8;
+    private final static short RES_XML_TYPE = 0x0003;
+
+    /*
+     * (non-Javadoc)
+     * @see org.eclipse.core.runtime.content.IContentDescriber#describe(java.io.
+     * InputStream, org.eclipse.core.runtime.content.IContentDescription)
+     */
+    public int describe(InputStream contents, IContentDescription description) throws IOException {
+        int length = 8;
+        byte[] bytes = new byte[length];
+        if (contents.read(bytes, 0, length) != length) {
+            return INVALID;
+        }
+        ByteBuffer buf = ByteBuffer.wrap(bytes);
+        buf.order(ByteOrder.LITTLE_ENDIAN);
+        short type = buf.getShort();
+        short headerSize = buf.getShort();
+        buf.getInt(); // chunk size
+        if (type == RES_XML_TYPE && headerSize == RES_XML_HEADER_SIZE) {
+            return VALID;
+        }
+        return INVALID;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see
+     * org.eclipse.core.runtime.content.IContentDescriber#getSupportedOptions()
+     */
+    public QualifiedName[] getSupportedOptions() {
+        return new QualifiedName[0];
+    }
+
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/binaryxml/BinaryXMLMultiPageEditorPart.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/binaryxml/BinaryXMLMultiPageEditorPart.java
new file mode 100644 (file)
index 0000000..a5dc667
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
+ *
+ * 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.ide.eclipse.adt.internal.editors.binaryxml;
+
+import com.android.ide.eclipse.adt.AdtPlugin;
+import com.android.sdklib.SdkConstants;
+
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.internal.core.JarEntryFile;
+import org.eclipse.jdt.internal.ui.javaeditor.JarEntryEditorInput;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.wst.xml.ui.internal.tabletree.XMLMultiPageEditorPart;
+
+import java.io.File;
+
+/**
+ * The XML editor is an editor that open Android xml files from the android.jar file
+ * <p>
+ * The editor checks if the file is contained in jar and is so,
+ * convert editor input to XmlStorageEditorInput that handles
+ * corresponding file from Android SDK.
+ *
+ */
+public class BinaryXMLMultiPageEditorPart extends XMLMultiPageEditorPart {
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.eclipse.ui.part.EditorPart#setInput(org.eclipse.ui.IEditorInput)
+     */
+    @Override
+    protected void setInput(IEditorInput input) {
+        if (input instanceof JarEntryEditorInput) {
+            JarEntryEditorInput jarInput = (JarEntryEditorInput) input;
+            IStorage storage = jarInput.getStorage();
+            if (storage instanceof JarEntryFile) {
+                JarEntryFile jarEntryFile = (JarEntryFile) storage;
+                IPackageFragmentRoot fragmentRoot = jarEntryFile.getPackageFragmentRoot();
+                if (fragmentRoot == null) {
+                    super.setInput(input);
+                    return;
+                }
+                IPath path = fragmentRoot.getPath();
+                if (path == null) {
+                    super.setInput(input);
+                    return;
+                }
+                path = path.removeLastSegments(1);
+                IPath filePath = path.append(SdkConstants.FD_DATA).append(
+                        jarEntryFile.getFullPath().toPortableString());
+                File file = new File(filePath.toOSString());
+                if (!(file.isFile())) {
+                    super.setInput(input);
+                    return;
+                }
+                try {
+                    XmlStorageEditorInput newInput = new XmlStorageEditorInput(
+                            new FileStorage(file));
+                    super.setInput(newInput);
+                    return;
+                } catch (Exception e) {
+                    AdtPlugin.log(e, e.getMessage(), null);
+                }
+            }
+        }
+        super.setInput(input);
+    }
+
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/binaryxml/FileStorage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/binaryxml/FileStorage.java
new file mode 100644 (file)
index 0000000..614ad0f
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
+ *
+ * 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.ide.eclipse.adt.internal.editors.binaryxml;
+
+import com.android.ide.eclipse.adt.AdtPlugin;
+
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+
+/**
+ * Implementation of storage for a local file
+ * (<code>java.io.File</code>).
+ *
+ * @see org.eclipse.core.resources.IStorage
+ */
+
+public class FileStorage implements IStorage {
+
+    /**
+     * The file this storage refers to.
+     */
+    private File mFile = null;
+
+    /**
+     * Constructs and returns storage for the given file.
+     *
+     * @param file a local file
+     */
+    public FileStorage(File file) {
+        mFile = file;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.core.resources.IStorage#getContents()
+     */
+    public InputStream getContents() throws CoreException {
+        InputStream stream = null;
+        try {
+            stream = new FileInputStream(mFile);
+        } catch (Exception e) {
+            throw new CoreException(new Status(IStatus.ERROR, AdtPlugin.getDefault().getBundle()
+                    .getSymbolicName(), IStatus.ERROR, mFile.getAbsolutePath(), e));
+        }
+        return stream;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.core.resources.IStorage#getFullPath()
+     */
+    public IPath getFullPath() {
+        return new Path(mFile.getAbsolutePath());
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.core.resources.IStorage#getName()
+     */
+    public String getName() {
+        return mFile.getName();
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.core.resources.IStorage#isReadOnly()
+     */
+    public boolean isReadOnly() {
+        return true;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.core.runtime.IAdaptable#getAdapter(Class)
+     */
+    public Object getAdapter(Class adapter) {
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof FileStorage) {
+            return mFile.equals(((FileStorage) obj).mFile);
+        }
+        return super.equals(obj);
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        return mFile.hashCode();
+    }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/binaryxml/XmlStorageEditorInput.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/binaryxml/XmlStorageEditorInput.java
new file mode 100644 (file)
index 0000000..d1e821e
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
+ *
+ * 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.ide.eclipse.adt.internal.editors.binaryxml;
+
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IPersistableElement;
+import org.eclipse.ui.IStorageEditorInput;
+
+/**
+ * An editor input for a local file.
+ */
+public class XmlStorageEditorInput implements IStorageEditorInput {
+
+    /**
+     * Storage associated with this editor input
+     */
+    IStorage mStorage = null;
+
+    /**
+     * Constructs an editor input on the given storage
+     *
+     * @param storage
+     */
+    public XmlStorageEditorInput(IStorage storage) {
+        mStorage = storage;
+    }
+
+    /* (non-Javadoc)
+     * @see IStorageEditorInput#getStorage()
+     */
+    public IStorage getStorage() throws CoreException {
+        return mStorage;
+    }
+
+    /* (non-Javadoc)
+     * @see IInput#getStorage()
+     */
+    public boolean exists() {
+        return mStorage != null;
+    }
+
+    /* (non-Javadoc)
+     * @see IEditorInput#getImageDescriptor()
+     */
+    public ImageDescriptor getImageDescriptor() {
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see IEditorInput#getName()
+     */
+    public String getName() {
+        return mStorage.getName();
+    }
+
+    /* (non-Javadoc)
+     * @see IEditorInput#getPersistable()
+     */
+    public IPersistableElement getPersistable() {
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see IEditorInput#getToolTipText()
+     */
+    public String getToolTipText() {
+        return mStorage.getFullPath() != null ? mStorage.getFullPath().toString() : mStorage
+                .getName();
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.core.runtime.IAdaptable#getAdapter(Class)
+     */
+    public Object getAdapter(Class adapter) {
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof XmlStorageEditorInput) {
+            return mStorage.equals(((XmlStorageEditorInput) obj).mStorage);
+        }
+        return super.equals(obj);
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        return mStorage.hashCode();
+    }
+}