| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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. |
| */ |
| package org.apache.ode.bpel.o; |
| |
| import javax.xml.namespace.QName; |
| import java.io.*; |
| import java.util.Arrays; |
| |
| /** |
| * Header written at the beginning of every compiled BPEL object file. |
| */ |
| public class Serializer { |
| |
| public static final byte[] MAGIC_NUMBER_OFH_20040908 = |
| new byte[] { 0x55, '5', 'S', 0x00, 'O', 'F', 'H', 0x20, 0x04, 0x09, 0x08 }; |
| |
| public static final byte[] MAGIC_NUMBER_OFH_20061101 = |
| new byte[] { 0x55, '5', 'S', 0x00, 'O', 'F', 'H', 0x20, 0x06, 0x11, 0x01 }; |
| |
| public static final byte[] MAGIC_NUMBER = MAGIC_NUMBER_OFH_20061101; |
| |
| public static final short FORMAT_SERIALIZED_JAVA14 = 0x01; |
| |
| // START PERSISTED FIELDS |
| public final byte[] magic = new byte[MAGIC_NUMBER.length]; |
| |
| /** Compiled Process representation format. */ |
| public short format; |
| |
| /** Time of compilation (system local time). */ |
| public long compileTime; |
| |
| /** Deprecated, only one process per file. */ |
| public final int numProcesses = 1; |
| |
| public InputStream _inputStream; |
| |
| public String guid; |
| |
| // public OProcess _oprocess; |
| |
| public QName type; |
| |
| |
| // END PERSISTED FIELDS |
| |
| public Serializer(long compileTime) { |
| System.arraycopy(MAGIC_NUMBER, 0, magic, 0, MAGIC_NUMBER.length); |
| this.format = FORMAT_SERIALIZED_JAVA14; |
| this.compileTime = compileTime; |
| } |
| |
| public Serializer() {} |
| |
| public Serializer(InputStream inputStream) throws IOException { |
| _inputStream = inputStream; |
| read(inputStream); |
| } |
| |
| |
| public void read(InputStream is) throws IOException { |
| DataInputStream oin = new DataInputStream(is); |
| byte[] magic = new byte[MAGIC_NUMBER.length]; |
| oin.read(magic, 0, magic.length); |
| |
| if (Arrays.equals(MAGIC_NUMBER_OFH_20040908, magic)) { |
| // Old format requires us to read the OModel to get the type and guid. |
| this.format = oin.readShort(); |
| this.compileTime = oin.readLong(); |
| oin.readInt(); |
| ObjectInputStream ois = new CustomObjectInputStream(_inputStream); |
| OProcess oprocess; |
| try { |
| oprocess = (OProcess) ois.readObject(); |
| } catch (ClassNotFoundException e) { |
| throw new IOException("DataStream Error"); |
| } |
| this.type = new QName(oprocess.targetNamespace, oprocess.processName); |
| this.guid = "OLD-FORMAT-NO-GUID"; |
| |
| return; |
| } |
| // The current (most recent) scheme |
| if (Arrays.equals(MAGIC_NUMBER, magic)) { |
| this.format = oin.readShort(); |
| this.compileTime = oin.readLong(); |
| this.guid = oin.readUTF(); |
| String tns = oin.readUTF(); |
| String name = oin.readUTF(); |
| this.type = new QName(tns, name); |
| return; |
| } |
| |
| throw new IOException("Unrecognized file format (bad magic number)."); |
| } |
| |
| public void writeOProcess(OProcess process, OutputStream os) throws IOException { |
| DataOutputStream out = new DataOutputStream(os); |
| |
| out.write(MAGIC_NUMBER); |
| out.writeShort(format); |
| out.writeLong(compileTime); |
| out.writeUTF(process.guid); |
| out.writeUTF(process.targetNamespace); |
| out.writeUTF(process.processName); |
| out.flush(); |
| ObjectOutputStream oos = new CustomObjectOutputStream(os); |
| oos.writeObject(process); |
| oos.flush(); |
| } |
| |
| public OProcess readOProcess() throws IOException, ClassNotFoundException { |
| // if (_oprocess != null) |
| // return _oprocess; |
| |
| ObjectInputStream ois = new CustomObjectInputStream(_inputStream); |
| OProcess oprocess; |
| try { |
| oprocess = (OProcess) ois.readObject(); |
| } catch (ClassNotFoundException e) { |
| throw new IOException("DataStream Error"); |
| } |
| |
| return oprocess; |
| } |
| |
| static class CustomObjectOutputStream extends ObjectOutputStream { |
| |
| /** |
| * @param out |
| * @throws IOException |
| */ |
| public CustomObjectOutputStream(OutputStream out) throws IOException { |
| super(out); |
| enableReplaceObject(true); |
| } |
| |
| protected Object replaceObject(Object obj) throws IOException{ |
| if(obj instanceof QName){ |
| QName q = (QName)obj; |
| return new OQName(q.getNamespaceURI(), q.getLocalPart(), q.getPrefix()); |
| } |
| return super.replaceObject(obj); |
| } |
| |
| } |
| |
| static class CustomObjectInputStream extends ObjectInputStream { |
| |
| /** |
| * @param in |
| * @throws IOException |
| */ |
| public CustomObjectInputStream(InputStream in) throws IOException { |
| super(in); |
| enableResolveObject(true); |
| } |
| |
| protected Object resolveObject(Object obj) throws IOException { |
| if(obj instanceof OQName){ |
| OQName q = (OQName)obj; |
| return new QName(q.uri, q.local, q.prefix); |
| } |
| return super.resolveObject(obj); |
| } |
| |
| /** |
| * Override coverts old class names into new class names to preserve compatibility with |
| * pre-Apache namespaces. |
| */ |
| @Override |
| protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException { |
| ObjectStreamClass read = super.readClassDescriptor(); |
| if (read.getName().startsWith("com.fs.pxe.")) { |
| return ObjectStreamClass.lookup(Class.forName(read.getName().replace("com.fs.pxe.", "org.apache.ode."))); |
| } |
| if (read.getName().startsWith("com.fs.utils.")) { |
| return ObjectStreamClass.lookup(Class.forName(read.getName().replace("com.fs.utils.", "org.apache.ode.utils."))); |
| } |
| return read; |
| } |
| |
| } |
| |
| static class OQName implements Serializable{ |
| |
| private static final long serialVersionUID = 1L; |
| |
| final String local; |
| final String uri; |
| final String prefix; |
| |
| OQName(String uri, String local, String prefix){ |
| this.uri = uri; |
| this.local = local; |
| this.prefix = prefix; |
| } |
| } |
| } |