/*
 * 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 org.apache.ode.bpel.o.OScope.Variable;
import org.apache.ode.utils.DOMUtils;
import org.w3c.dom.Document;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class OAssign extends OActivity {
    static final long serialVersionUID = -1L  ;
    
    public final List<Copy> copy = new ArrayList<Copy>();

    public OAssign(OProcess owner, OActivity parent) {
        super(owner, parent);
    }


    public String toString() {
        return "{OAssign : " + name + ", joinCondition=" + joinCondition + "}";
    }

    /**
     * Assignmenet copy entry, i.e. what the assignment consits of.
     */
    public static class Copy extends OBase {
        private static final long serialVersionUID = 1L;
        public LValue to;
        public RValue from;
        public boolean keepSrcElementName;

        public Copy(OProcess owner) {
            super(owner);
        }

        public String toString() {
            return "{OCopy " + to + "=" + from + "}";
        }
    }

    public interface LValue {
        OScope.Variable getVariable();
    }

    public interface RValue { }

    public static class Literal extends OBase implements RValue {
        private static final long serialVersionUID = 1L;
        public transient Document xmlLiteral;

        public Literal(OProcess owner, Document xmlLiteral) {
            super(owner);
            if (xmlLiteral == null)
                throw new IllegalArgumentException("null xmlLiteral!");
            this.xmlLiteral = xmlLiteral;
        }

        public String toString() {
            return "{Literal " + xmlLiteral + "}";
        }

        private void writeObject(java.io.ObjectOutputStream out)
                throws IOException
        {
            out.writeUTF(DOMUtils.domToString(xmlLiteral));
        }

        private void readObject(java.io.ObjectInputStream in)
                throws IOException
        {
            String domStr = in.readUTF();
            try {
                xmlLiteral = DOMUtils.stringToDOM(domStr).getOwnerDocument();
            } catch (Exception ex) {
                throw (IOException)(new IOException("XML de-serialization error.")).initCause(ex);
            }
        }

    }

    public static class LValueExpression extends OBase implements LValue {
        private static final long serialVersionUID = 1L;
        public OLValueExpression expression;

        public LValueExpression(OProcess owner, OLValueExpression compiledExpression) {
            super(owner);
            this.expression = compiledExpression;
        }

        public String toString() {
            return expression.toString();
        }
        /**
         * @see org.apache.ode.bpel.o.OAssign.LValue#getVariable()
         */
        public Variable getVariable() {
            return expression.getVariable();
        }
      
    }
    public static class Expression extends OBase implements RValue {
        private static final long serialVersionUID = 1L;
        public OExpression expression;

        public Expression(OProcess owner, OExpression compiledExpression) {
            super(owner);
            this.expression = compiledExpression;
        }

        public String toString() {
            return expression.toString();
        }
    }

    public static class VariableRef extends OBase implements RValue, LValue {
        private static final long serialVersionUID = 1L;
        public OScope.Variable variable;
        public OMessageVarType.Part part;
        public OExpression location;

        public VariableRef(OProcess owner) {
            super(owner);
        }

        public OScope.Variable getVariable() {
            return variable;
        }

        /**
         * Report whether this is a reference to a whole "message"
         * @return <code>true</code> if whole-message reference
         */
        public boolean isMessageRef() { 
            return variable.type instanceof OMessageVarType && 
            part == null && location == null;
        }
        
        /**
         * Report whether this is a reference to a message part. 
         * @return <code>true</code> if reference to a message part
         */
        public boolean isPartRef() {
            return variable.type instanceof OMessageVarType && 
            part != null && location == null;
        }
        
        public String toString() {
            return "{VarRef " + variable  +
                    (part==null ? "" : "." + part.name) +
                    (location == null ? "" : location.toString())+ "}";
        }
    }

    public static class PropertyRef extends OBase implements RValue, LValue {
        private static final long serialVersionUID = 1L;
        public OScope.Variable variable;
        public OProcess.OPropertyAlias propertyAlias;

        public PropertyRef(OProcess owner) { super(owner); }

        public OScope.Variable getVariable() {
            return variable;
        }

        public String toString() {
            return "{PropRef " + variable + "!" + propertyAlias+ "}";
        }
    }

    public static class PartnerLinkRef extends OBase implements RValue, LValue {
          private static final long serialVersionUID = 1L;
          public OPartnerLink partnerLink;
          public boolean isMyEndpointReference;

          public PartnerLinkRef(OProcess owner) { super(owner); }

          // Must fit in a LValue even if it's not variable based
          public Variable getVariable() {
              return null;
          }

          public String toString() {
              return "{PLinkRef " + partnerLink + "!" + isMyEndpointReference + "}";
          }
    }
}

@@ -2613,19 +2613,22 @@
 ut.write
-UTF
+Object
 (DOMUtil
@@ -2805,21 +2805,243 @@
 r = 
-in.readUTF();
+null;%0A            try %7B%0A                domStr = (String) in.readObject();%0A            %7D catch (ClassNotFoundException e) %7B%0A                throw (IOException)(new IOException(%22XML de-serialization error.%22)).initCause(e);%0A            %7D
 %0A   

The writeUTF method has a 64k limitation that can be annoying for BIG literals.