package org.jboss.seam.remoting;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import org.jboss.seam.remoting.model.Model;
import org.jboss.seam.remoting.wrapper.BeanWrapper;
import org.jboss.seam.remoting.wrapper.Wrapper;
/**
* @author Shane Bryzak
*/
public class MarshalUtils {
private static final byte[] RESULT_TAG_OPEN = "<result>".getBytes();
private static final byte[] RESULT_TAG_CLOSE = "</result>".getBytes();
private static final byte[] MODEL_TAG_OPEN_START = "<model id=\"".getBytes();
private static final byte[] MODEL_TAG_OPEN_END = "\">".getBytes();
private static final byte[] MODEL_TAG_CLOSE = "</model>".getBytes();
private static final byte[] VALUE_TAG_OPEN = "<value>".getBytes();
private static final byte[] VALUE_TAG_CLOSE = "</value>".getBytes();
private static final byte[] ALIASED_VALUE_TAG_OPEN_START = "<value alias=\"".getBytes();
private static final byte[] ALIASED_VALUE_TAG_OPEN_END = "\">".getBytes();
private static final byte[] ALIASED_VALUE_TAG_CLOSE = "</value>".getBytes();
private static final byte[] EXCEPTION_TAG_OPEN = "<exception>".getBytes();
private static final byte[] EXCEPTION_TAG_CLOSE = "</exception>".getBytes();
private static final byte[] EXCEPTION_CLASS_TAG_OPEN = "<class>".getBytes();
private static final byte[] EXCEPTION_CLASS_TAG_CLOSE = "</class>".getBytes();
private static final byte[] MESSAGE_TAG_OPEN = "<message>".getBytes();
private static final byte[] MESSAGE_TAG_CLOSE = "</message>".getBytes();
public static void marshalCallResult(Call call, OutputStream out)
throws IOException {
out.write(RESULT_TAG_OPEN);
if (call.getException() != null) {
marshalException(call.getException(), call.getContext(), out);
} else {
out.write(VALUE_TAG_OPEN);
call.getContext().createWrapperFromObject(call.getResult(), "")
.marshal(out);
out.write(VALUE_TAG_CLOSE);
out.write(RequestHandler.REFS_TAG_OPEN);
marshalRefs(call.getContext().getOutRefs(), call.getConstraints(), out);
out.write(RequestHandler.REFS_TAG_CLOSE);
}
out.write(RESULT_TAG_CLOSE);
}
public static void marshalException(Throwable exception, CallContext ctx, OutputStream out)
throws IOException {
out.write(EXCEPTION_TAG_OPEN);
out.write(EXCEPTION_CLASS_TAG_OPEN);
ctx.createWrapperFromObject(exception.getClass().getName(), "").marshal(out);
out.write(EXCEPTION_CLASS_TAG_CLOSE);
out.write(MESSAGE_TAG_OPEN);
ctx.createWrapperFromObject(exception.getMessage(), "").marshal(out);
out.write(MESSAGE_TAG_CLOSE);
out.write(EXCEPTION_TAG_CLOSE);
}
public static void marshalModel(Model model, OutputStream out)
throws IOException {
out.write(MODEL_TAG_OPEN_START);
out.write(model.getId().getBytes());
out.write(MODEL_TAG_OPEN_END);
for (String alias : model.getBeanProperties().keySet()) {
Model.BeanProperty property = model.getBeanProperties().get(alias);
out.write(ALIASED_VALUE_TAG_OPEN_START);
out.write(alias.getBytes());
out.write(ALIASED_VALUE_TAG_OPEN_END);
model.getCallContext().createWrapperFromObject(property.getValue(), "")
.marshal(out);
out.write(ALIASED_VALUE_TAG_CLOSE);
}
out.write(RequestHandler.REFS_TAG_OPEN);
marshalRefs(model.getCallContext().getOutRefs(), null, out);
out.write(RequestHandler.REFS_TAG_CLOSE);
out.write(MODEL_TAG_CLOSE);
}
public static void marshalModelExpand(Model model, Wrapper value,
OutputStream out, int newRefIdx)
throws IOException {
out.write(MODEL_TAG_OPEN_START);
out.write(model.getId().getBytes());
out.write(MODEL_TAG_OPEN_END);
out.write(RESULT_TAG_OPEN);
value.marshal(out);
out.write(RESULT_TAG_CLOSE);
if (model.getCallContext().getOutRefs().size() > newRefIdx) {
out.write(RequestHandler.REFS_TAG_OPEN);
marshalNewRefs(model.getCallContext().getOutRefs(), newRefIdx, null, out);
out.write(RequestHandler.REFS_TAG_CLOSE);
}
out.write(MODEL_TAG_CLOSE);
}
public static void marshalNewRefs(List<Wrapper> refs, int startIdx,
List<String> constraints, OutputStream out)
throws IOException {
for (int i = startIdx; i < refs.size(); i++) {
Wrapper wrapper = refs.get(i);
out.write(RequestHandler.REF_TAG_OPEN_START);
out.write(Integer.toString(i).getBytes());
out.write(RequestHandler.REF_TAG_OPEN_END);
if (wrapper instanceof BeanWrapper && constraints != null) {
((BeanWrapper) wrapper).serialize(out, constraints);
} else {
wrapper.serialize(out);
}
out.write(RequestHandler.REF_TAG_CLOSE);
}
}
public static void marshalRefs(List<Wrapper> refs, List<String> constraints,
OutputStream out)
throws IOException {
for (int i = 0; i < refs.size(); i++) {
Wrapper wrapper = refs.get(i);
out.write(RequestHandler.REF_TAG_OPEN_START);
out.write(Integer.toString(i).getBytes());
out.write(RequestHandler.REF_TAG_OPEN_END);
if (wrapper instanceof BeanWrapper && constraints != null) {
((BeanWrapper) wrapper).serialize(out, constraints);
} else {
wrapper.serialize(out);
}
out.write(RequestHandler.REF_TAG_CLOSE);
}
}
}