| package org.apache.ode.bpel.obj.serde; |
| |
| import java.io.BufferedInputStream; |
| import java.io.DataInputStream; |
| import java.io.DataOutputStream; |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileNotFoundException; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.ObjectInputStream; |
| import java.io.ObjectOutputStream; |
| import java.io.OutputStream; |
| import java.util.Arrays; |
| import java.util.Map; |
| |
| import javax.xml.namespace.QName; |
| |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import org.apache.ode.bpel.o.Serializer; |
| import org.apache.ode.bpel.obj.OProcess; |
| import org.apache.ode.bpel.obj.OProcessWrapper; |
| import org.apache.ode.bpel.obj.migrate.ObjectTraverser; |
| import org.apache.ode.bpel.obj.migrate.OmUpgradeVisitor; |
| import org.apache.ode.bpel.obj.migrate.UpgradeChecker; |
| import org.apache.ode.bpel.obj.serde.OmSerdeFactory.SerializeFormat; |
| |
| /** |
| * Main Serializer and Deserializer of OModel classes. This class handles different |
| * serialization format. (De)Serialize header information. It will upgrade the deserialized |
| * OProcess to newest version. And write it back if the write back file is specified. |
| * @see OmSerdeFactory |
| */ |
| public class DeSerializer { |
| private static final Log __log = LogFactory.getLog(DeSerializer.class); |
| |
| private OProcessWrapper wrapper = new OProcessWrapper(); |
| private InputStream is; |
| private File writeBackFile; |
| private File cbpFile; |
| |
| /** |
| * Constructor to create deserializer to deserialize from file. |
| * @param cbpFile the serialized compiled cbp file |
| * @throws FileNotFoundException |
| */ |
| public DeSerializer(File cbpFile) throws FileNotFoundException { |
| this(new FileInputStream(cbpFile)); |
| this.cbpFile = cbpFile; |
| } |
| |
| DeSerializer(InputStream is) { |
| this.is = new BufferedInputStream(is); |
| deserializeHeader(); |
| } |
| |
| /** |
| * Constructor to create serializer. |
| */ |
| public DeSerializer() { |
| } |
| |
| public void serialize(OutputStream out, OProcess process) { |
| serialize(out, process, OmSerdeFactory.FORMAT_SERIALIZED_DEFAULT); |
| } |
| |
| public void serialize(OutputStream out, OProcess process, |
| SerializeFormat format) { |
| wrapper.setCompileTime(System.currentTimeMillis()); |
| wrapper.setProcess(process); |
| wrapper.setFormat(format); |
| serialize(out); |
| } |
| |
| private void serialize(OutputStream out) { |
| try { |
| DataOutputStream dos = new DataOutputStream(out); |
| dos.write(wrapper.getMagic()); |
| ObjectOutputStream oos = new ObjectOutputStream(out); |
| oos.writeObject(wrapper.getFormat()); |
| oos.writeLong(wrapper.getCompileTime()); |
| oos.writeObject(wrapper.getGuid()); |
| oos.writeObject(wrapper.getType()); |
| oos.writeObject(wrapper.getOtherHeaders()); |
| } catch (IOException e1) { |
| SerializaionRtException e = new SerializaionRtException( |
| "Error when serialize Headers."); |
| e.initCause(e1); |
| throw e; |
| } |
| OmSerdeFactory factory = new OmSerdeFactory(); |
| factory.setFormat(wrapper.getFormat()); |
| OmSerializer serializer = factory.createOmSerializer(out, |
| wrapper.getProcess()); |
| serializer.serialize(); |
| } |
| |
| private void deserializeHeader() { |
| try { |
| DataInputStream oin = new DataInputStream(is); |
| oin.mark(OProcessWrapper.CURRENT_MAGIC_NUMBER.length + 2); |
| byte[] magic = new byte[OProcessWrapper.CURRENT_MAGIC_NUMBER.length]; |
| oin.read(magic, 0, magic.length); |
| if (Arrays.equals(Serializer.MAGIC_NUMBER_OFH_20040908, magic) |
| || Arrays.equals(Serializer.MAGIC_NUMBER_OFH_20061101, |
| magic)) { |
| oin.reset(); |
| Serializer serializer = new Serializer(is); |
| wrapper.setMagic(magic); |
| wrapper.setGuid(serializer.guid); |
| wrapper.setCompileTime(serializer.compileTime); |
| wrapper.setType(serializer.type); |
| wrapper.setFormat(SerializeFormat.FORMAT_SERIALIZED_LEGACY); |
| } else { |
| ObjectInputStream ois = new ObjectInputStream(is); |
| wrapper = new OProcessWrapper(); |
| wrapper.setMagic(magic); |
| wrapper.setFormat((SerializeFormat) ois.readObject()); |
| wrapper.setCompileTime(ois.readLong()); |
| wrapper.setGuid((String) ois.readObject()); |
| wrapper.setType((QName) ois.readObject()); |
| wrapper.setOtherHeaders((Map<String, Object>) (ois.readObject())); |
| wrapper.checkValid(); |
| } |
| } catch (Exception e1) { |
| try { |
| is.close(); |
| } catch (IOException e2) { |
| e2.printStackTrace(); |
| } |
| SerializaionRtException e = new SerializaionRtException( |
| "Error when reading Headers during deseriazation"); |
| e.initCause(e1); |
| throw e; |
| } |
| } |
| |
| /** |
| * Deserialize the compiled <code>OProcess</code>. |
| * @return The deserialized OProcess |
| */ |
| public OProcess deserialize() { |
| OmSerdeFactory factory = new OmSerdeFactory(); |
| factory.setFormat(wrapper.getFormat()); |
| OProcess process = null; |
| try { |
| OmDeserializer de = factory.createOmDeserializer(is); |
| process = de.deserialize(); |
| } finally { |
| if (cbpFile != null) { |
| //this means that <code>is</code> is constructed from cbpFile, |
| // and we are reaponsible to close it. |
| try { |
| is.close(); |
| } catch (IOException e) { |
| e.printStackTrace(); |
| } |
| } |
| } |
| wrapper.setProcess(process); |
| //upgrade |
| UpgradeChecker checker = new UpgradeChecker(); |
| ObjectTraverser traverser = new ObjectTraverser(); |
| traverser.accept(checker); |
| traverser.traverseObject(process); |
| if (!checker.isNewest()) { |
| OmUpgradeVisitor upgrader = new OmUpgradeVisitor(); |
| traverser = new ObjectTraverser(); |
| traverser.accept(upgrader); |
| traverser.traverseObject(process); |
| writeBack(); |
| } |
| return process; |
| } |
| |
| private void writeBack() { |
| if (writeBackFile == null && cbpFile == null) { |
| // we dont kown where to writeback; |
| return; |
| } |
| if (writeBackFile == null) { |
| // write back to original cbp file; |
| writeBackFile = cbpFile; |
| } |
| byte[] magic = wrapper.getMagic(); |
| if (Arrays.equals(Serializer.MAGIC_NUMBER_OFH_20040908, magic) |
| || Arrays.equals(Serializer.MAGIC_NUMBER_OFH_20061101, magic)) { |
| //upgrade to new omodel magic and format |
| wrapper.setMagic(OProcessWrapper.CURRENT_MAGIC_NUMBER); |
| wrapper.setFormat(OmSerdeFactory.FORMAT_SERIALIZED_DEFAULT); |
| } |
| OutputStream wbStream = null; |
| if (writeBackFile.exists()) { |
| if (writeBackFile.renameTo(new File(writeBackFile.getAbsolutePath() |
| + ".bak"))) { |
| try { |
| wbStream = new FileOutputStream(writeBackFile); |
| serialize(wbStream); |
| } catch (FileNotFoundException e) { |
| __log.info("Error when write back upgraded process. file not found"); |
| } finally { |
| if (wbStream != null) { |
| try { |
| wbStream.close(); |
| } catch (IOException e) { |
| e.printStackTrace(); |
| } |
| } |
| } |
| } else { |
| __log.debug("backup file failed. skip writing back upgraded file"); |
| } |
| } |
| } |
| |
| public OProcessWrapper getWrapper() { |
| return wrapper; |
| } |
| |
| public void setWrapper(OProcessWrapper wrapper) { |
| this.wrapper = wrapper; |
| } |
| |
| public void setWriteBackFile(File writeBack) { |
| this.writeBackFile = writeBack; |
| } |
| } |