diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 8d35cb3..0000000 --- a/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -__pycache__ -*.pyc diff --git a/LICENSE b/LICENSE deleted file mode 100644 index d645695..0000000 --- a/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - - 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. diff --git a/README.md b/ProjectHome.md similarity index 51% rename from README.md rename to ProjectHome.md index 1da7d95..a9c2c6e 100644 --- a/README.md +++ b/ProjectHome.md @@ -1,45 +1,42 @@ -# python-javaobj - -python-javaobj is a python library that provides functions for reading and writing (writing is WIP currently) Java objects -serialized or will be deserialized by _ObjectOutputStream_. This form of object +python-javaobj is a python library that provides functions for reading (writing is WIP) of Java objects +serialized or will be deserialized by ObjectOutputStream. This form of object representation is a standard data interchange format in Java world. javaobj module exposes an API familiar to users of the standard library marshal, pickle and json modules. -## Features +## Features ## - * Java object instance unmarshaling - * Java classes unmarshaling - * Primitive values unmarshaling - * Automatic conversion of Java Collections to python ones (_HashMap_ => dict, _ArrayList_ => list, etc) - -## Requirements + * Java object instance unmarshaling + * Java class itself unmarshaling + * Primitive values unmarshaling + * Automatic conversion of Java Collections to python ones (HashMap => dict, ArrayList => list, etc) - * Python >= 2.6, but < 3.0 (porting to 3.0 is in progress) - * Maven 2+ (for building test data of serialized objects. You can skip it if you do not plan to run tests.py) +## Requirements ## -## Usage + * Python >= 2.6 -Unmarshalling of Java serialised object: +## Usage ## -```python -import javaobj +Unmarshalling of Java serialised object: -jobj = self.read_file("obj5.ser") -pobj = javaobj.loads(jobj) -print pobj +``` +import javaobj + +jobj = self.read_file("obj5.ser") +pobj = javaobj.loads(jobj) +print pobj ``` Or, you can use Unmarshaller object directly: -```python -import javaobj - -marshaller = javaobj.JavaObjectUnmarshaller(open("sunExample.ser")) -pobj = marshaller.readObject() - -self.assertEqual(pobj.value, 17) -self.assertTrue(pobj.next) - -pobj = marshaller.readObject() ``` +import javaobj + +marshaller = javaobj.JavaObjectUnmarshaller(open("sunExample.ser")) +pobj = marshaller.readObject() + +self.assertEqual(pobj.value, 17) +self.assertTrue(pobj.next) + +pobj = marshaller.readObject() +``` \ No newline at end of file diff --git a/java/pom.xml b/java/pom.xml deleted file mode 100644 index c4ed820..0000000 --- a/java/pom.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - 4.0.0 - - org.python-javaobj - python-javaobj - 1.0-SNAPSHOT - - - - - junit - junit - 4.9 - test - - - - - \ No newline at end of file diff --git a/java/src/test/java/CollectionsTest.java b/java/src/test/java/CollectionsTest.java deleted file mode 100644 index 12c1b53..0000000 --- a/java/src/test/java/CollectionsTest.java +++ /dev/null @@ -1,57 +0,0 @@ -import java.io.FileOutputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.Map; -import java.util.Queue; -import java.util.concurrent.ConcurrentLinkedQueue; - -import org.junit.Test; - -class CollectionsSerializableBean implements Serializable { - // Collections - public Collection arrayList; - public Collection linkedList; - public Map hashMap; - public Queue queue; - - public CollectionsSerializableBean() - { - super(); - - arrayList = new ArrayList(); - arrayList.add("e1"); - arrayList.add("e2"); - - linkedList = new LinkedList(); - linkedList.add("ll1"); - linkedList.add("ll2"); - - hashMap = new HashMap(); - hashMap.put("k1", null); - hashMap.put("k2", "value2"); - hashMap.put("k3", arrayList); - hashMap.put("k3", linkedList); - - queue = new ConcurrentLinkedQueue(); - queue.add("q1"); - queue.add("q2"); - queue.add("q3"); - } -} - -public class CollectionsTest { - - ObjectOutputStream oos; - FileOutputStream fos; - - @Test - public void testCollections() throws Exception { - oos = new ObjectOutputStream(fos = new FileOutputStream("objCollections.ser")); - oos.writeObject(new CollectionsSerializableBean()); - oos.flush(); - } -} diff --git a/java/src/test/java/JFrameTest.java b/java/src/test/java/JFrameTest.java deleted file mode 100644 index a3e3463..0000000 --- a/java/src/test/java/JFrameTest.java +++ /dev/null @@ -1,144 +0,0 @@ -import java.awt.BorderLayout; -import java.awt.Component; -import java.awt.GridLayout; -import java.awt.Rectangle; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.io.Serializable; - -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JFrame; -import javax.swing.JList; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTextArea; -import javax.swing.ListCellRenderer; -import javax.swing.ListModel; -import javax.swing.ListSelectionModel; -import javax.swing.UIManager; -import javax.swing.border.EmptyBorder; - -public class JFrameTest extends JFrame { - - public JFrameTest() { - super("CheckList Example"); - String[] strs = { "swing", "home", "basic", "metal", "JList" }; - - final JList list = new JList(createData(strs)); - - list.setCellRenderer(new CheckListRenderer()); - list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - list.setBorder(new EmptyBorder(0, 4, 0, 0)); - list.addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e) { - int index = list.locationToIndex(e.getPoint()); - CheckableItem item = (CheckableItem) list.getModel() - .getElementAt(index); - item.setSelected(!item.isSelected()); - Rectangle rect = list.getCellBounds(index, index); - list.repaint(rect); - } - }); - JScrollPane sp = new JScrollPane(list); - - final JTextArea textArea = new JTextArea(3, 10); - JScrollPane textPanel = new JScrollPane(textArea); - JButton printButton = new JButton("print"); - printButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - ListModel model = list.getModel(); - int n = model.getSize(); - for (int i = 0; i < n; i++) { - CheckableItem item = (CheckableItem) model.getElementAt(i); - if (item.isSelected()) { - textArea.append(item.toString()); - textArea.append(System.getProperty("line.separator")); - } - } - } - }); - JButton clearButton = new JButton("clear"); - clearButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - textArea.setText(""); - } - }); - JPanel panel = new JPanel(new GridLayout(2, 1)); - panel.add(printButton); - panel.add(clearButton); - - getContentPane().add(sp, BorderLayout.CENTER); - getContentPane().add(panel, BorderLayout.EAST); - getContentPane().add(textPanel, BorderLayout.SOUTH); - } - - private CheckableItem[] createData(String[] strs) { - int n = strs.length; - CheckableItem[] items = new CheckableItem[n]; - for (int i = 0; i < n; i++) { - items[i] = new CheckableItem(strs[i]); - } - return items; - } - - class CheckableItem implements Serializable { - private String str; - - private boolean isSelected; - - public CheckableItem(String str) { - this.str = str; - isSelected = false; - } - - public void setSelected(boolean b) { - isSelected = b; - } - - public boolean isSelected() { - return isSelected; - } - - public String toString() { - return str; - } - } - - class CheckListRenderer extends JCheckBox implements ListCellRenderer { - - public CheckListRenderer() { - setBackground(UIManager.getColor("List.textBackground")); - setForeground(UIManager.getColor("List.textForeground")); - } - - public Component getListCellRendererComponent(JList list, Object value, - int index, boolean isSelected, boolean hasFocus) { - setEnabled(list.isEnabled()); - setSelected(((CheckableItem) value).isSelected()); - setFont(list.getFont()); - setText(value.toString()); - return this; - } - } - - public static void main(String args[]) { - try { - UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); - } catch (Exception evt) { - } - - JFrameTest frame = new JFrameTest(); - frame.addWindowListener(new WindowAdapter() { - public void windowClosing(WindowEvent e) { - System.exit(0); - } - }); - frame.setSize(300, 200); - frame.setVisible(true); - } -} \ No newline at end of file diff --git a/java/src/test/java/OneTest.java b/java/src/test/java/OneTest.java deleted file mode 100644 index 171d483..0000000 --- a/java/src/test/java/OneTest.java +++ /dev/null @@ -1,321 +0,0 @@ -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.io.ByteArrayOutputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.util.Hashtable; -import java.util.Vector; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestName; - -import javax.swing.*; - -class MyExceptionWhenDumping implements java.io.Serializable { - private static class MyException extends java.io.IOException { - }; - - public boolean anInstanceVar = false; - - public MyExceptionWhenDumping() { - super(); - } - - private void readObject(java.io.ObjectInputStream in) - throws java.io.IOException, ClassNotFoundException { - in.defaultReadObject(); - } - - private void writeObject(java.io.ObjectOutputStream out) - throws java.io.IOException, ClassNotFoundException { - throw new MyException(); - } -} - -enum Color -{ - RED("RED"), GREEN("GREEN"), BLUE("BLUE"), UNKNOWN("UNKNOWN"); - private final String value; - - Color(String value) - { - this.value = value; - } - - public String getValue() - { - return value; - } -} - -class ClassWithEnum implements Serializable { - public Color color = Color.GREEN; - public Color[] colors = {Color.GREEN, Color.BLUE, Color.RED}; -} - -class SuperAaaa implements Serializable { - - public String superString = "Super!!"; - public int integer = -1; - public boolean bool = true; - -} - -class TestConcrete extends SuperAaaa implements Serializable { - - public String childString = "Child!!"; - - TestConcrete() { - super(); - } - -} - -public class OneTest { - - @Rule - public TestName name = new TestName(); - - ObjectOutputStream oos; - ByteArrayOutputStream bao; - FileOutputStream fos; - - public class SerializableTestHelper implements Serializable { - - public String aField1; - - public String aField2; - - SerializableTestHelper() { - aField1 = null; - aField2 = null; - } - - SerializableTestHelper(String s, String t) { - aField1 = s; - aField2 = t; - } - - private void readObject(ObjectInputStream ois) throws Exception { - // note aField2 is not read - ObjectInputStream.GetField fields = ois.readFields(); - aField1 = (String) fields.get("aField1", "Zap"); - } - - private void writeObject(ObjectOutputStream oos) throws IOException { - // note aField2 is not written - ObjectOutputStream.PutField fields = oos.putFields(); - fields.put("aField1", aField1); - oos.writeFields(); - } - - public String getText1() { - return aField1; - } - - public void setText1(String s) { - aField1 = s; - } - - public String getText2() { - return aField2; - } - - public void setText2(String s) { - aField2 = s; - } - } - - public static class A1 implements Serializable { - private static final long serialVersionUID = 5942584913446079661L; - B1 b1 = new B1(); - B1 b2 = b1; - Vector v = new Vector(); - } - - public static class B1 implements Serializable { - int i = 5; - Hashtable h = new Hashtable(); - } - - @Before - public void setUp() throws Exception { - oos = new ObjectOutputStream(fos = new FileOutputStream(name.getMethodName() + ".ser")); - } - - @Test - public void testDouble() throws IOException { - oos.writeDouble(Double.MAX_VALUE); - oos.close(); - } - - @Test - public void testBytes() throws IOException { - oos.writeBytes("HelloWorld"); - oos.close(); - } - - @Test - public void testBoolean() throws IOException { - oos.writeBoolean(false); - oos.close(); - } - - @Test - public void testByte() throws IOException { - oos.writeByte(127); - oos.close(); - } - - @Test - public void testChar() throws IOException { - oos.writeChar('C'); - oos.close(); - } - - @Test - public void test_readFields() throws Exception { - oos.writeObject(new SerializableTestHelper("Gabba", "Jabba")); - oos.flush(); - } - - @Test - public void testClass() throws Exception { - oos.writeObject(String.class); - oos.flush(); - } - - @Test - public void testSwingObject() throws Exception { - JFrameTest frame = new JFrameTest(); - frame.addWindowListener(new WindowAdapter() { - public void windowClosing(WindowEvent e) { - System.exit(0); - } - }); - frame.setSize(300, 200); - frame.setVisible(true); - oos.writeObject(((JScrollPane)frame.getRootPane().getContentPane().getComponent(0)).getComponent(1)); - oos.flush(); - } - - @Test - public void testSuper() throws Exception { - oos = new ObjectOutputStream(fos = new FileOutputStream("objSuper.ser")); - TestConcrete ts = new TestConcrete(); - -// ts.setChild("and Child!!!!"); - oos.writeObject(ts); - oos.flush(); - } - - @Test - public void testEnums() throws Exception { - oos = new ObjectOutputStream(fos = new FileOutputStream("objEnums.ser")); - ClassWithEnum ts = new ClassWithEnum(); - - oos.writeObject(ts); - oos.flush(); - } - - @Test - public void testException() throws Exception { - oos = new ObjectOutputStream(fos = new FileOutputStream("objException.ser")); - MyExceptionWhenDumping ts = new MyExceptionWhenDumping(); - - oos.writeObject(ts); - oos.flush(); - } - -// public void test_readObject() throws Exception { -// String s = "HelloWorld"; -// oos.writeObject(s); -// oos.close(); -// ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray())); -// assertEquals("Read incorrect Object value", s, ois.readObject()); -// ois.close(); -// -// // Regression for HARMONY-91 -// // dynamically create serialization byte array for the next hierarchy: -// // - class A implements Serializable -// // - class C extends A -// -// byte[] cName = C.class.getName().getBytes("UTF-8"); -// byte[] aName = A.class.getName().getBytes("UTF-8"); -// -// ByteArrayOutputStream out = new ByteArrayOutputStream(); -// -// byte[] begStream = new byte[] { (byte) 0xac, (byte) 0xed, // STREAM_MAGIC -// (byte) 0x00, (byte) 0x05, // STREAM_VERSION -// (byte) 0x73, // TC_OBJECT -// (byte) 0x72, // TC_CLASSDESC -// (byte) 0x00, // only first byte for C class name length -// }; -// -// out.write(begStream, 0, begStream.length); -// out.write(cName.length); // second byte for C class name length -// out.write(cName, 0, cName.length); // C class name -// -// byte[] midStream = new byte[] { (byte) 0x00, (byte) 0x00, (byte) 0x00, -// (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, -// (byte) 0x21, // serialVersionUID = 33L -// (byte) 0x02, // flags -// (byte) 0x00, (byte) 0x00, // fields : none -// (byte) 0x78, // TC_ENDBLOCKDATA -// (byte) 0x72, // Super class for C: TC_CLASSDESC for A class -// (byte) 0x00, // only first byte for A class name length -// }; -// -// out.write(midStream, 0, midStream.length); -// out.write(aName.length); // second byte for A class name length -// out.write(aName, 0, aName.length); // A class name -// -// byte[] endStream = new byte[] { (byte) 0x00, (byte) 0x00, (byte) 0x00, -// (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, -// (byte) 0x0b, // serialVersionUID = 11L -// (byte) 0x02, // flags -// (byte) 0x00, (byte) 0x01, // fields -// -// (byte) 0x4c, // field description: type L (object) -// (byte) 0x00, (byte) 0x04, // length -// // field = 'name' -// (byte) 0x6e, (byte) 0x61, (byte) 0x6d, (byte) 0x65, -// -// (byte) 0x74, // className1: TC_STRING -// (byte) 0x00, (byte) 0x12, // length -// // -// (byte) 0x4c, (byte) 0x6a, (byte) 0x61, (byte) 0x76, -// (byte) 0x61, (byte) 0x2f, (byte) 0x6c, (byte) 0x61, -// (byte) 0x6e, (byte) 0x67, (byte) 0x2f, (byte) 0x53, -// (byte) 0x74, (byte) 0x72, (byte) 0x69, (byte) 0x6e, -// (byte) 0x67, (byte) 0x3b, -// -// (byte) 0x78, // TC_ENDBLOCKDATA -// (byte) 0x70, // NULL super class for A class -// -// // classdata -// (byte) 0x74, // TC_STRING -// (byte) 0x00, (byte) 0x04, // length -// (byte) 0x6e, (byte) 0x61, (byte) 0x6d, (byte) 0x65, // value -// }; -// -// out.write(endStream, 0, endStream.length); -// out.flush(); -// -// // read created serial. form -// ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream( -// out.toByteArray())); -// Object o = ois.readObject(); -// assertEquals(C.class, o.getClass()); -// -// // Regression for HARMONY-846 -// assertNull(new ObjectInputStream() {}.readObject()); -// } - - -} diff --git a/javaobj.py b/javaobj.py deleted file mode 100644 index 2422d73..0000000 --- a/javaobj.py +++ /dev/null @@ -1,863 +0,0 @@ -# Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 -# -# 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. - -""" -Provides functions for reading (writing is WIP currently) of Java -objects serialized by ObjectOutputStream. This form of object -representation is a standard data interchange format in Java world. - -javaobj module exposes an API familiar to users of the standard modules -such as marshal, pickle and json. - -See: http://download.oracle.com/javase/6/docs/platform/serialization/spec/protocol.html -""" - -import StringIO -import struct - -try: - import logging -except ImportError: - def log_debug(message, ident=0): - pass - def log_error(message, ident=0): - pass -else: - _log = logging.getLogger(__name__) - def log_debug(message, ident=0): - _log.debug(" " * (ident * 2) + str(message)) - def log_error(message, ident=0): - _log.error(" " * (ident * 2) + str(message)) - -__version__ = "$Revision: 20 $" - - -def load(file_object, *args): - """ - Deserializes Java primitive data and objects serialized by ObjectOutputStream - from a file-like object. - """ - marshaller = JavaObjectUnmarshaller(file_object) - for t in args: - marshaller.add_transformer(t) - marshaller.add_transformer(DefaultObjectTransformer()) - return marshaller.readObject() - - -def load_all(file_object): - marshaller = JavaObjectUnmarshaller(file_object) - marshaller.add_transformer(DefaultObjectTransformer()) - - res = [] - while marshaller.data_left: - res.append(marshaller.readObject()) - return res - - -def loads(string, *args): - """ - Deserializes Java objects and primitive data serialized by ObjectOutputStream - from a string. - """ - f = StringIO.StringIO(string) - marshaller = JavaObjectUnmarshaller(f) - for t in args: - marshaller.add_transformer(t) - marshaller.add_transformer(DefaultObjectTransformer()) - return marshaller.readObject() - - -def dumps(object, *args): - """ - Serializes Java primitive data and objects unmarshaled by load(s) before into string. - """ - marshaller = JavaObjectMarshaller() - for t in args: - marshaller.add_transformer(t) - return marshaller.dump(object) - - -class JavaClass(object): - def __init__(self): - self.name = None - self.serialVersionUID = None - self.flags = None - self.handle = None - self.fields_names = [] - self.fields_types = [] - self.superclass = None - - def __str__(self): - return self.__repr__() - - def __repr__(self): - return "[%s:0x%X]" % (self.name, self.serialVersionUID) - - def __eq__(self, other): - if not isinstance(other, type(self)): - return False - return (self.name == other.name and - self.serialVersionUID == other.serialVersionUID and - self.flags == other.flags and - self.fields_names == other.fields_names and - self.fields_types == other.fields_types and - self.superclass == other.superclass) - - -class JavaObject(object): - - def __init__(self): - self.classdesc = None - self.annotations = [] - - def get_class(self): - return self.classdesc - - def __str__(self): - return self.__repr__() - - def __repr__(self): - name = "UNKNOWN" - if self.classdesc: - name = self.classdesc.name - return "" % name - - def __eq__(self, other): - if not isinstance(other, type(self)): - return False - res = (self.classdesc == other.classdesc and - self.annotations == other.annotations) - for name in self.classdesc.fields_names: - res = (res and - getattr(self, name) == getattr(other, name)) - return res - - def copy(self, new_object): - new_object.classdesc = self.classdesc - new_object.annotations = self.annotations - - for name in self.classdesc.fields_names: - new_object.__setattr__(name, getattr(self, name)) - - -class JavaString(str): - def __init__(self, *args, **kwargs): - str.__init__(self, *args, **kwargs) - - def __eq__(self, other): - if not isinstance(other, str): - return False - return str.__eq__(self, other) - - -class JavaEnum(JavaObject): - def __init__(self, constant=None): - super(JavaEnum, self).__init__() - self.constant = constant - - -class JavaArray(list, JavaObject): - def __init__(self, classdesc=None): - list.__init__(self) - JavaObject.__init__(self) - self.classdesc = classdesc - - -class JavaObjectConstants: - - STREAM_MAGIC = 0xaced - STREAM_VERSION = 0x05 - - TC_NULL = 0x70 - TC_REFERENCE = 0x71 - TC_CLASSDESC = 0x72 - TC_OBJECT = 0x73 - TC_STRING = 0x74 - TC_ARRAY = 0x75 - TC_CLASS = 0x76 - TC_BLOCKDATA = 0x77 - TC_ENDBLOCKDATA = 0x78 - TC_RESET = 0x79 - TC_BLOCKDATALONG = 0x7A - TC_EXCEPTION = 0x7B - TC_LONGSTRING = 0x7C - TC_PROXYCLASSDESC = 0x7D - TC_ENUM = 0x7E - TC_MAX = 0x7E - - # classDescFlags - SC_WRITE_METHOD = 0x01 # if SC_SERIALIZABLE - SC_BLOCK_DATA = 0x08 # if SC_EXTERNALIZABLE - SC_SERIALIZABLE = 0x02 - SC_EXTERNALIZABLE = 0x04 - SC_ENUM = 0x10 - - # type definition chars (typecode) - TYPE_BYTE = 'B' # 0x42 - TYPE_CHAR = 'C' - TYPE_DOUBLE = 'D' # 0x44 - TYPE_FLOAT = 'F' # 0x46 - TYPE_INTEGER = 'I' # 0x49 - TYPE_LONG = 'J' # 0x4A - TYPE_SHORT = 'S' # 0x53 - TYPE_BOOLEAN = 'Z' # 0x5A - TYPE_OBJECT = 'L' # 0x4C - TYPE_ARRAY = '[' # 0x5B - - # list of supported typecodes listed above - TYPECODES_LIST = [ - # primitive types - TYPE_BYTE, - TYPE_CHAR, - TYPE_DOUBLE, - TYPE_FLOAT, - TYPE_INTEGER, - TYPE_LONG, - TYPE_SHORT, - TYPE_BOOLEAN, - # object types - TYPE_OBJECT, - TYPE_ARRAY ] - - BASE_REFERENCE_IDX = 0x7E0000 - - -class JavaObjectUnmarshaller(JavaObjectConstants): - - def __init__(self, stream=None): - self.opmap = { - self.TC_NULL: self.do_null, - self.TC_CLASSDESC: self.do_classdesc, - self.TC_OBJECT: self.do_object, - self.TC_STRING: self.do_string, - self.TC_LONGSTRING: self.do_string_long, - self.TC_ARRAY: self.do_array, - self.TC_CLASS: self.do_class, - self.TC_BLOCKDATA: self.do_blockdata, - self.TC_BLOCKDATALONG: self.do_blockdata_long, - self.TC_REFERENCE: self.do_reference, - self.TC_ENUM: self.do_enum, - self.TC_ENDBLOCKDATA: self.do_null, # note that we are reusing of do_null - } - self.current_object = None - self.reference_counter = 0 - self.references = [] - self.object_stream = stream - self._readStreamHeader() - self.object_transformers = [] - self.data_left = True - - def readObject(self): - try: - opcode, res = self._read_and_exec_opcode(ident=0) # TODO: add expects - - position_bak = self.object_stream.tell() - the_rest = self.object_stream.read() - if len(the_rest): - log_error("Warning!!!!: Stream still has %s bytes left. Enable debug mode of logging to see the hexdump." % len(the_rest)) - log_debug(self._create_hexdump(the_rest, position_bak)) - self.data_left = True - else: - log_debug("Java Object unmarshalled succesfully!") - self.data_left = False - self.object_stream.seek(position_bak) - - return res - except Exception as e: - self._oops_dump_state() - raise - - def add_transformer(self, transformer): - self.object_transformers.append(transformer) - - def _readStreamHeader(self): - (magic, version) = self._readStruct(">HH") - if magic != self.STREAM_MAGIC or version != self.STREAM_VERSION: - raise IOError("The stream is not java serialized object. Invalid stream header: %04X%04X" % (magic, version)) - - def _read_and_exec_opcode(self, ident=0, expect=None): - position = self.object_stream.tell() - (opid, ) = self._readStruct(">B") - log_debug("OpCode: 0x%X (at offset: 0x%X)" % (opid, position), ident) - if expect and opid not in expect: - raise IOError("Unexpected opcode 0x%X" % opid) - handler = self.opmap.get(opid) - if not handler: - raise RuntimeError("Unknown OpCode in the stream: 0x%x" % opid) - return (opid, handler(ident=ident)) - - def _readStruct(self, unpack): - length = struct.calcsize(unpack) - ba = self.object_stream.read(length) - if len(ba) != length: - raise RuntimeError("Stream has been ended unexpectedly while unmarshaling. (%d vs %d)" % (len(ba), length)) - return struct.unpack(unpack, ba) - - def _readString(self, mod="H"): - (length, ) = self._readStruct(">" + mod) - ba = self.object_stream.read(length) - return ba - - def do_classdesc(self, parent=None, ident=0): - # TC_CLASSDESC className serialVersionUID newHandle classDescInfo - # classDescInfo: - # classDescFlags fields classAnnotation superClassDesc - # classDescFlags: - # (byte) // Defined in Terminal Symbols and Constants - # fields: - # (short) fieldDesc[count] - - # fieldDesc: - # primitiveDesc - # objectDesc - # primitiveDesc: - # prim_typecode fieldName - # objectDesc: - # obj_typecode fieldName className1 - clazz = JavaClass() - log_debug("[classdesc]", ident) - ba = self._readString() - clazz.name = ba - log_debug("Class name: %s" % ba, ident) - (serialVersionUID, newHandle, classDescFlags) = self._readStruct(">LLB") - clazz.serialVersionUID = serialVersionUID - clazz.flags = classDescFlags - clazz.handle = newHandle - - self._add_reference(clazz, ident) - - log_debug("Serial: 0x%X newHandle: 0x%X. classDescFlags: 0x%X" % (serialVersionUID, newHandle, classDescFlags), ident) - (length, ) = self._readStruct(">H") - log_debug("Fields num: 0x%X" % length, ident) - - clazz.fields_names = [] - clazz.fields_types = [] - for fieldId in range(length): - (typecode, ) = self._readStruct(">B") - field_name = self._readString() - field_type = None - field_type = self._convert_char_to_type(typecode) - - if field_type == self.TYPE_ARRAY: - opcode, field_type = self._read_and_exec_opcode(ident=ident+1, expect=[self.TC_STRING, self.TC_REFERENCE]) - assert type(field_type) is JavaString -# if field_type is not None: -# field_type = "array of " + field_type -# else: -# field_type = "array of None" - elif field_type == self.TYPE_OBJECT: - opcode, field_type = self._read_and_exec_opcode(ident=ident+1, expect=[self.TC_STRING, self.TC_REFERENCE]) - assert type(field_type) is JavaString - - log_debug("FieldName: 0x%X" % typecode + " " + str(field_name) + " " + str(field_type), ident) - assert field_name is not None - assert field_type is not None - - clazz.fields_names.append(field_name) - clazz.fields_types.append(field_type) - if parent: - parent.__fields = clazz.fields_names - parent.__types = clazz.fields_types - # classAnnotation - (opid, ) = self._readStruct(">B") - log_debug("OpCode: 0x%X" % opid, ident) - if opid != self.TC_ENDBLOCKDATA: - raise NotImplementedError("classAnnotation isn't implemented yet") - # superClassDesc - opcode, superclassdesc = self._read_and_exec_opcode(ident=ident+1, expect=[self.TC_CLASSDESC, self.TC_NULL, self.TC_REFERENCE]) - log_debug(str(superclassdesc), ident) - clazz.superclass = superclassdesc - - return clazz - - def do_blockdata(self, parent=None, ident=0): - # TC_BLOCKDATA (unsigned byte) (byte)[size] - log_debug("[blockdata]", ident) - (length, ) = self._readStruct(">B") - ba = self.object_stream.read(length) - return ba - - def do_blockdata_long(self, parent=None, ident=0): - # TC_BLOCKDATALONG (int) (byte)[size] - log_debug("[blockdata]", ident) - (length, ) = self._readStruct(">I") - ba = self.object_stream.read(length) - return ba - - def do_class(self, parent=None, ident=0): - # TC_CLASS classDesc newHandle - log_debug("[class]", ident) - - # TODO: what to do with "(ClassDesc)prevObject". (see 3rd line for classDesc:) - opcode, classdesc = self._read_and_exec_opcode(ident=ident+1, expect=[self.TC_CLASSDESC, self.TC_PROXYCLASSDESC, self.TC_NULL, self.TC_REFERENCE]) - log_debug("Classdesc: %s" % classdesc, ident) - self._add_reference(classdesc, ident) - return classdesc - - def do_object(self, parent=None, ident=0): - # TC_OBJECT classDesc newHandle classdata[] // data for each class - java_object = JavaObject() - log_debug("[object]", ident) - log_debug("java_object.annotations just after instantination: " + str(java_object.annotations), ident) - - # TODO: what to do with "(ClassDesc)prevObject". (see 3rd line for classDesc:) - opcode, classdesc = self._read_and_exec_opcode(ident=ident+1, expect=[self.TC_CLASSDESC, self.TC_PROXYCLASSDESC, self.TC_NULL, self.TC_REFERENCE]) - # self.TC_REFERENCE hasn't shown in spec, but actually is here - - self._add_reference(java_object, ident) - - # classdata[] - - # Store classdesc of this object - java_object.classdesc = classdesc - - if classdesc.flags & self.SC_EXTERNALIZABLE and not classdesc.flags & self.SC_BLOCK_DATA: - raise NotImplementedError("externalContents isn't implemented yet") # TODO: - - if classdesc.flags & self.SC_SERIALIZABLE: - # create megalist - tempclass = classdesc - megalist = [] - megatypes = [] - while tempclass: - log_debug(">>> " + str(tempclass.fields_names) + " " + str(tempclass), ident) - log_debug(">>> " + str(tempclass.fields_types), ident) - fieldscopy = tempclass.fields_names[:] - fieldscopy.extend(megalist) - megalist = fieldscopy - - fieldscopy = tempclass.fields_types[:] - fieldscopy.extend(megatypes) - megatypes = fieldscopy - - tempclass = tempclass.superclass - - log_debug("Values count: %s" % str(len(megalist)), ident) - log_debug("Prepared list of values: %s" % str(megalist), ident) - log_debug("Prepared list of types: %s" % str(megatypes), ident) - - for field_name, field_type in zip(megalist, megatypes): - res = self._read_value(field_type, ident, name=field_name) - java_object.__setattr__(field_name, res) - - if classdesc.flags & self.SC_SERIALIZABLE and classdesc.flags & self.SC_WRITE_METHOD or classdesc.flags & self.SC_EXTERNALIZABLE and classdesc.flags & self.SC_BLOCK_DATA: - # objectAnnotation - log_debug("java_object.annotations before: " + str(java_object.annotations), ident) - while opcode != self.TC_ENDBLOCKDATA: - opcode, obj = self._read_and_exec_opcode(ident=ident+1) # , expect=[self.TC_ENDBLOCKDATA, self.TC_BLOCKDATA, self.TC_OBJECT, self.TC_NULL, self.TC_REFERENCE]) - if opcode != self.TC_ENDBLOCKDATA: - java_object.annotations.append(obj) - log_debug("objectAnnotation value: " + str(obj), ident) - log_debug("java_object.annotations after: " + str(java_object.annotations), ident) - - # Transform object - for transformer in self.object_transformers: - tmp_object = transformer.transform(java_object) - if tmp_object is not java_object: - java_object = tmp_object - break - - log_debug(">>> java_object: " + str(java_object), ident) - return java_object - - def do_string(self, parent=None, ident=0): - log_debug("[string]", ident) - ba = JavaString(self._readString()) - self._add_reference(ba, ident) - return ba - - def do_string_long(self, parent=None, ident=0): - log_debug("[long string]", ident) - ba = JavaString(self._readString("Q")) - self._add_reference(ba, ident) - return ba - - def do_array(self, parent=None, ident=0): - # TC_ARRAY classDesc newHandle (int) values[size] - log_debug("[array]", ident) - opcode, classdesc = self._read_and_exec_opcode(ident=ident+1, expect=[self.TC_CLASSDESC, self.TC_PROXYCLASSDESC, self.TC_NULL, self.TC_REFERENCE]) - - array = JavaArray(classdesc) - - self._add_reference(array, ident) - - (size, ) = self._readStruct(">i") - log_debug("size: " + str(size), ident) - - type_char = classdesc.name[0] - assert type_char == self.TYPE_ARRAY - type_char = classdesc.name[1] - - if type_char == self.TYPE_OBJECT or type_char == self.TYPE_ARRAY: - for i in range(size): - opcode, res = self._read_and_exec_opcode(ident=ident+1) - log_debug("Object value: %s" % str(res), ident) - array.append(res) - else: - for i in range(size): - res = self._read_value(type_char, ident) - log_debug("Native value: %s" % str(res), ident) - array.append(res) - - return array - - def do_reference(self, parent=None, ident=0): - (handle, ) = self._readStruct(">L") - log_debug("## Reference handle: 0x%x" % (handle), ident) - return self.references[handle - self.BASE_REFERENCE_IDX] - - def do_null(self, parent=None, ident=0): - return None - - def do_enum(self, parent=None, ident=0): - # TC_ENUM classDesc newHandle enumConstantName - enum = JavaEnum() - opcode, classdesc = self._read_and_exec_opcode(ident=ident+1, expect=[self.TC_CLASSDESC, self.TC_PROXYCLASSDESC, self.TC_NULL, self.TC_REFERENCE]) - enum.classdesc = classdesc - self._add_reference(enum, ident) - opcode, enumConstantName = self._read_and_exec_opcode(ident=ident+1, expect=[self.TC_STRING, self.TC_REFERENCE]) - - enum.constant = enumConstantName - return enum - - def _create_hexdump(self, src, start_offset=0, length=16): - FILTER = ''.join([(len(repr(chr(x)))==3) and chr(x) or '.' for x in range(256)]) - result = [] - for i in xrange(0, len(src), length): - s = src[i:i+length] - hexa = ' '.join(["%02X" % ord(x) for x in s]) - printable = s.translate(FILTER) - result.append("%04X %-*s %s\n" % (i+start_offset, length*3, hexa, printable)) - return ''.join(result) - - def _read_value(self, field_type, ident, name = ""): - if len(field_type) > 1: - cls = field_type[1:] - field_type = field_type[0] # We don't need details for arrays and objects - - if field_type == self.TYPE_BOOLEAN: - (val, ) = self._readStruct(">B") - res = bool(val) - elif field_type == self.TYPE_BYTE: - (res, ) = self._readStruct(">b") - elif field_type == self.TYPE_SHORT: - (res, ) = self._readStruct(">h") - elif field_type == self.TYPE_INTEGER: - (res, ) = self._readStruct(">i") - elif field_type == self.TYPE_LONG: - (res, ) = self._readStruct(">q") - elif field_type == self.TYPE_FLOAT: - (res, ) = self._readStruct(">f") - elif field_type == self.TYPE_DOUBLE: - (res, ) = self._readStruct(">d") - elif field_type == self.TYPE_OBJECT or field_type == self.TYPE_ARRAY: - try: - opcode, res = self._read_and_exec_opcode(ident=ident+1) - except RuntimeError: - if cls == 'java/lang/String;': - res = JavaString(self._readString()) - else: - raise - else: - raise RuntimeError("Unknown typecode: %s" % field_type) - log_debug("* %s %s: " % (field_type, name) + str(res), ident) - return res - - def _convert_char_to_type(self, type_char): - typecode = type_char - if type(type_char) is int: - typecode = chr(type_char) - - if typecode in self.TYPECODES_LIST: - return typecode - else: - raise RuntimeError("Typecode %s (%s) isn't supported." % (type_char, typecode)) - - def _add_reference(self, obj, ident=0): - log_debug('## New reference handle 0x%X' % (len(self.references) + self.BASE_REFERENCE_IDX,), ident) - self.references.append(obj) - - def _oops_dump_state(self): - log_error("==Oops state dump" + "=" * (30 - 17)) - log_error("References: %s" % str(self.references)) - log_error("Stream seeking back at -16 byte (2nd line is an actual position!):") - self.object_stream.seek(-16, 1) - position = self.object_stream.tell() - the_rest = self.object_stream.read() - if len(the_rest): - log_error(self._create_hexdump(the_rest, position)) - log_error("=" * 30) - - -class JavaObjectMarshaller(JavaObjectConstants): - - def __init__(self, stream=None): - self.object_stream = stream - self.object_transformers = [] - - def add_transformer(self, transformer): - self.object_transformers.append(transformer) - - def dump(self, obj): - - self.object_obj = obj - self.object_stream = StringIO.StringIO() - self._writeStreamHeader() - self.writeObject(obj) - return self.object_stream.getvalue() - - def _writeStreamHeader(self): - self._writeStruct(">HH", 4, (self.STREAM_MAGIC, self.STREAM_VERSION)) - - def writeObject(self, obj): - log_debug("Writing object of type " + str(type(obj)) + " " + str(obj)) - if isinstance(obj, JavaArray): - self.write_array(obj) - elif isinstance(obj, JavaEnum): - self.write_enum(obj) - elif isinstance(obj, JavaObject): - self.write_object(obj) - elif isinstance(obj, JavaString): - self.write_string(obj) - elif isinstance(obj, JavaClass): - self.write_class(obj) - elif obj is None: - self.write_null() - elif type(obj) is str: - self.write_blockdata(obj) - else: - raise RuntimeError("Object serialization of type %s is not supported." % str(type(obj))) - - def _writeStruct(self, unpack, length, args): - ba = struct.pack(unpack, *args) - self.object_stream.write(ba) - - def _writeString(self, string): - length = len(string) - self._writeStruct(">H", 2, (length, )) - self.object_stream.write(string) - - def write_string(self, obj): - self._writeStruct(">B", 1, (self.TC_STRING,)) - self._writeString(obj) - - def write_enum(self, obj): - self._writeStruct(">B", 1, (self.TC_ENUM, )) - self.write_classdesc(obj.get_class()) - - self.write_string(obj.constant) - - def write_blockdata(self, obj, parent=None): - # TC_BLOCKDATA (unsigned byte) (byte)[size] - length = len(obj) - if length <= 256: - self._writeStruct(">B", 1, (self.TC_BLOCKDATA, )) - self._writeStruct(">B", 1, (length, )) - else: - self._writeStruct(">B", 1, (self.TC_BLOCKDATALONG, )) - self._writeStruct(">I", 1, (length, )) - self.object_stream.write(obj) - - def write_null(self): - self._writeStruct(">B", 1, (self.TC_NULL, )) - - def write_object(self, obj, parent=None): - - # Transform object - for transformer in self.object_transformers: - tmp_object = transformer.transform(obj) - if tmp_object is not obj: - obj = tmp_object - break - - self._writeStruct(">B", 1, (self.TC_OBJECT, )) - cls = obj.get_class() - self.write_classdesc(cls) - - all_names = [] - all_types = [] - tmpcls = cls - while tmpcls: - all_names += tmpcls.fields_names - all_types += tmpcls.fields_types - tmpcls = tmpcls.superclass - - del tmpcls - for name, type in zip(all_names, all_types): - try: - self._write_value(type, getattr(obj, name)) - except AttributeError as e: - log_error("%s e, %s %s" % (str(e), repr(obj), repr(dir(obj)))) - raise - - del all_names, all_types - - if (cls.flags & self.SC_SERIALIZABLE and cls.flags & self.SC_WRITE_METHOD or - cls.flags & self.SC_EXTERNALIZABLE and cls.flags & self.SC_BLOCK_DATA): - for annot in obj.annotations: - log_debug("Write annotation %s for %s" % (repr(annot), repr(obj),)) - if annot == None: - self.write_null() - else: - self.writeObject(annot) - self._writeStruct('>B', 1, (self.TC_ENDBLOCKDATA,)) - - def write_class(self, obj, parent=None): - self._writeStruct(">B", 1, (self.TC_CLASS,)) - self.write_classdesc(obj) - - def write_classdesc(self, obj, parent=None): - self._writeStruct(">B", 1, (self.TC_CLASSDESC, )) - self._writeString(obj.name) - self._writeStruct(">LLB", 1, (obj.serialVersionUID, obj.handle, obj.flags)) - self._writeStruct(">H", 1, (len(obj.fields_names), )) - - for name,type in zip(obj.fields_names, obj.fields_types): - self._writeStruct(">B", 1, - (self._convert_type_to_char(type),)) - self._writeString(name) - if type[0] in (self.TYPE_OBJECT, self.TYPE_ARRAY): - self.write_string(type) - - self._writeStruct(">B", 1, (self.TC_ENDBLOCKDATA,)) - if obj.superclass: - self.write_classdesc(obj.superclass) - else: - self.write_null() - - def write_array(self, obj): - self._writeStruct(">B", 1, (self.TC_ARRAY,)) - self.write_classdesc(obj.get_class()) - self._writeStruct(">i", 1, (len(obj),)) - - classdesc = obj.get_class() - - type_char = classdesc.name[0] - assert type_char == self.TYPE_ARRAY - type_char = classdesc.name[1] - - if type_char == self.TYPE_OBJECT: - for o in obj: - self.write_object(o) - elif type_char == self.TYPE_ARRAY: - for a in obj: - self.write_array(a) - else: - log_debug("Write array of type %s" % type_char) - for v in obj: - self._write_value(type_char, v) - - def _write_value(self, field_type, value): - if len(field_type) > 1: - field_type = field_type[0] # We don't need details for arrays and objects - - if field_type == self.TYPE_BOOLEAN: - self._writeStruct(">B", 1, (1 if value else 0,)) - elif field_type == self.TYPE_BYTE: - if value > 127: - self._writeStruct(">B", 1, (value,)) - else: - self._writeStruct(">b", 1, (value,)) - elif field_type == self.TYPE_SHORT: - self._writeStruct(">h", 1, (value,)) - elif field_type == self.TYPE_INTEGER: - self._writeStruct(">i", 1, (value,)) - elif field_type == self.TYPE_LONG: - self._writeStruct(">q", 1, (value,)) - elif field_type == self.TYPE_FLOAT: - self._writeStruct(">f", 1, (value,)) - elif field_type == self.TYPE_DOUBLE: - self._writeStruct(">d", 1, (value,)) - elif field_type == self.TYPE_OBJECT or field_type == self.TYPE_ARRAY: - if value == None: - self.write_null() - elif isinstance(value, JavaEnum): - self.write_enum(value) - elif isinstance(value, JavaObject): - self.write_object(value) - elif isinstance(value, JavaString): - self.write_string(value) - elif isinstance(value, str): - self.write_blockdata(value) - else: - raise RuntimeError("Unknown typecode: %s" % field_type) - else: - raise RuntimeError("Unknown typecode: %s" % field_type) - - def _convert_type_to_char(self, type_char): - typecode = type_char - if type(type_char) is int: - typecode = chr(type_char) - - if typecode in self.TYPECODES_LIST: - return ord(typecode) - elif len(typecode) > 1: - if typecode[0] == 'L': - return ord(self.TYPE_OBJECT) - elif typecode[0] == '[': - return ord(self.TYPE_ARRAY) - - raise RuntimeError("Typecode %s (%s) isn't supported." % (type_char, typecode)) - -class DefaultObjectTransformer(object): - - class JavaList(list, JavaObject): - def __init__(self, *args, **kwargs): - list.__init__(self, *args, **kwargs) - JavaObject.__init__(self) - - class JavaMap(dict, JavaObject): - def __init__(self, *args, **kwargs): - dict.__init__(self, *args, **kwargs) - JavaObject.__init__(self) - - def transform(self, object): - if object.get_class().name == "java.util.ArrayList": - # * @serialData The length of the array backing the ArrayList - # * instance is emitted (int), followed by all of its elements - # * (each an Object) in the proper order. - #print "---" - #print "java.util.ArrayList" - #print object.annotations - #print "---" - new_object = self.JavaList() - object.copy(new_object) - new_object.extend(object.annotations[1:]) - #print ">>> object:", new_object - return new_object - if object.get_class().name == "java.util.LinkedList": - #print "---" - #print - #print "java.util.LinkedList" - #print object.annotations - #print "---" - new_object = self.JavaList() - object.copy(new_object) - new_object.extend(object.annotations[1:]) - #print ">>> object:", new_object - return new_object - if object.get_class().name == "java.util.HashMap": - #print "---" - #print - #print "java.util.HashMap" - #print object.annotations - #print "---" - new_object = self.JavaMap() - object.copy(new_object) - - for i in range(1, len(object.annotations),2): - new_object[object.annotations[i]] = object.annotations[i+1] - - #print ">>> object:", new_object - return new_object - - return object diff --git a/obj0.ser b/obj0.ser deleted file mode 100644 index 04492ad..0000000 Binary files a/obj0.ser and /dev/null differ diff --git a/obj1.ser b/obj1.ser deleted file mode 100644 index fcbe5be..0000000 Binary files a/obj1.ser and /dev/null differ diff --git a/obj2.ser b/obj2.ser deleted file mode 100644 index 09c2231..0000000 Binary files a/obj2.ser and /dev/null differ diff --git a/obj3.ser b/obj3.ser deleted file mode 100644 index 4af86bd..0000000 Binary files a/obj3.ser and /dev/null differ diff --git a/obj4.ser b/obj4.ser deleted file mode 100644 index 15670ec..0000000 Binary files a/obj4.ser and /dev/null differ diff --git a/obj5.ser b/obj5.ser deleted file mode 100644 index 52f5b03..0000000 Binary files a/obj5.ser and /dev/null differ diff --git a/obj6.ser b/obj6.ser deleted file mode 100644 index 14c84e2..0000000 Binary files a/obj6.ser and /dev/null differ diff --git a/obj7.ser b/obj7.ser deleted file mode 100644 index 21c10e0..0000000 Binary files a/obj7.ser and /dev/null differ diff --git a/objArrays.ser b/objArrays.ser deleted file mode 100644 index 6bc071b..0000000 Binary files a/objArrays.ser and /dev/null differ diff --git a/objCollections.ser b/objCollections.ser deleted file mode 100644 index f6ef1fc..0000000 Binary files a/objCollections.ser and /dev/null differ diff --git a/objEnums.ser b/objEnums.ser deleted file mode 100644 index 90b5784..0000000 Binary files a/objEnums.ser and /dev/null differ diff --git a/objException.ser b/objException.ser deleted file mode 100644 index 70a43e1..0000000 Binary files a/objException.ser and /dev/null differ diff --git a/objSuper.ser b/objSuper.ser deleted file mode 100644 index 02b779d..0000000 Binary files a/objSuper.ser and /dev/null differ diff --git a/setup.py b/setup.py deleted file mode 100644 index 64a3964..0000000 --- a/setup.py +++ /dev/null @@ -1,26 +0,0 @@ -import os -from setuptools import setup - -setup( - name="javaobj", - version="0.1.0", - author="Volodymyr Buell", - author_email="vbuell@gmail.com", - url="http://code.google.com/p/python-javaobj", - description=("Module for serializing and de-serializing Java objects."), - license="APL2", - keywords="python java marshalling serialization", -# packages=['javaobj'], - py_modules = ['javaobj'], - test_suite = "tests", - long_description="Provides functions for reading and writing (writing is WIP currently) " \ - "Java objects serialized or will be deserialized by ObjectOutputStream. " \ - "This form of object representation is a standard data interchange format " \ - "in Java world. javaobj module exposes an API familiar to users of the " \ - "standard library marshal, pickle and json modules.", - classifiers=[ - "Development Status :: 3 - Alpha", - "License :: OSI Approved :: Apache Software License", - "Topic :: Software Development :: Libraries :: Python Modules", - ], - ) \ No newline at end of file diff --git a/sunExample.ser b/sunExample.ser deleted file mode 100644 index c2554be..0000000 Binary files a/sunExample.ser and /dev/null differ diff --git a/tests.py b/tests.py deleted file mode 100644 index f37ac95..0000000 --- a/tests.py +++ /dev/null @@ -1,184 +0,0 @@ -import unittest -import javaobj -import logging - -class TestJavaobj(unittest.TestCase): - - @classmethod - def setUpClass(clazz): - import sys - import os - from subprocess import call - os.chdir('./java') - logging.basicConfig(level=logging.DEBUG, stream=sys.stdout) - call(['mvn', 'test']) - os.chdir('..') - - def setUp(self): - pass - - def read_file(self, filename): - file = open(filename, 'rb') - return file.read() - - def test_0_rw(self): - jobj = self.read_file("java/testChar.ser") - pobj = javaobj.loads(jobj) - print pobj - self.assertEqual(pobj, '\x00C') - jobj_ = javaobj.dumps(pobj) - self.assertEqual(jobj, jobj_) - - def test_1(self): - jobj = self.read_file("java/testDouble.ser") - pobj = javaobj.loads(jobj) - print pobj - self.assertEqual(pobj, '\x7f\xef\xff\xff\xff\xff\xff\xff') - jobj_ = javaobj.dumps(pobj) - self.assertEqual(jobj, jobj_) - - def test_2(self): - jobj = self.read_file("java/testBytes.ser") - pobj = javaobj.loads(jobj) - print pobj - self.assertEqual(pobj, 'HelloWorld') - jobj_ = javaobj.dumps(pobj) - self.assertEqual(jobj, jobj_) - - def test_3(self): - jobj = self.read_file("java/testBoolean.ser") - pobj = javaobj.loads(jobj) - print pobj - self.assertEqual(pobj, chr(0)) - jobj_ = javaobj.dumps(pobj) - self.assertEqual(jobj, jobj_) - -# def test_4(self): -# jobj = self.read_file("java/testByte.ser") -# pobj = javaobj.loads(jobj) -# print pobj -# self.assertEqual(pobj, 127) -# -# jobj_ = javaobj.dumps(pobj) -# self.assertEqual(jobj, jobj_) - - def test_5(self): - jobj = self.read_file("java/test_readFields.ser") - pobj = javaobj.loads(jobj) - print pobj - - self.assertEqual(pobj.aField1, 'Gabba') - self.assertEqual(pobj.aField2, None) - - classdesc = pobj.get_class() - self.assertTrue(classdesc) - self.assertEqual(classdesc.serialVersionUID, 0x7F0941F5) - self.assertEqual(classdesc.name, "OneTest$SerializableTestHelper") - print classdesc - print classdesc.flags - print classdesc.fields_names - print classdesc.fields_types - self.assertEqual(len(classdesc.fields_names), 3) - -# jobj_ = javaobj.dumps(pobj) -# self.assertEqual(jobj, jobj_) - - def test_6(self): - jobj = self.read_file("java/testClass.ser") - pobj = javaobj.loads(jobj) - print pobj - self.assertEqual(pobj.name, 'java.lang.String') - -# jobj_ = javaobj.dumps(pobj) -# self.assertEqual(jobj, jobj_) - -# def test_7(self): -# jobj = self.read_file("java/testSwingObject.ser") -# pobj = javaobj.loads(jobj) -# print pobj -# -# classdesc = pobj.get_class() -# print classdesc -# print classdesc.fields_names -# print classdesc.fields_types - -# def test_super(self): -# jobj = self.read_file("objSuper.ser") -# pobj = javaobj.loads(jobj) -# print pobj -# -# classdesc = pobj.get_class() -# print classdesc -# print classdesc.fields_names -# print classdesc.fields_types -# -# print pobj.childString -# print pobj.bool -# print pobj.integer -# -# def test_arrays(self): -# jobj = self.read_file("objArrays.ser") -# pobj = javaobj.loads(jobj) -# print pobj -# -# classdesc = pobj.get_class() -# print classdesc -# print classdesc.fields_names -# print classdesc.fields_types -# -## public String[] stringArr = {"1", "2", "3"}; -## public int[] integerArr = {1,2,3}; -## public boolean[] boolArr = {true, false, true}; -## public TestConcrete[] concreteArr = {new TestConcrete(), new TestConcrete()}; -# -# print pobj.stringArr -# print pobj.integerArr -# print pobj.boolArr -# print pobj.concreteArr -# -# def test_enums(self): -# jobj = self.read_file("objEnums.ser") -# pobj = javaobj.loads(jobj) -# print pobj -# -# classdesc = pobj.get_class() -# print classdesc -# print classdesc.fields_names -# print classdesc.fields_types -# -# def test_exception(self): -# jobj = self.read_file("objException.ser") -# pobj = javaobj.loads(jobj) -# print pobj -# -# classdesc = pobj.get_class() -# print classdesc -# print classdesc.fields_names -# print classdesc.fields_types -# -# def test_sun_example(self): -# marshaller = javaobj.JavaObjectUnmarshaller(open("sunExample.ser")) -# pobj = marshaller.readObject() -# -# self.assertEqual(pobj.value, 17) -# self.assertTrue(pobj.next) -# -# pobj = marshaller.readObject() -# -# self.assertEqual(pobj.value, 19) -# self.assertFalse(pobj.next) -# - def test_collections(self): - jobj = self.read_file("objCollections.ser") - pobj = javaobj.loads(jobj) - print pobj -# -# print "arrayList:", pobj.arrayList -# self.assertTrue(isinstance(pobj.arrayList, list)) -# print "hashMap:", pobj.hashMap -# self.assertTrue(isinstance(pobj.hashMap, dict)) -# print "linkedList:", pobj.linkedList -# self.assertTrue(isinstance(pobj.linkedList, list)) # Fails - -if __name__ == '__main__': - unittest.main()