public Object transform()

in modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/Output2OutputTransformer.java [165:326]


    public Object transform(Object response, TransformationContext context) {
        try {
            
            DataType<List<DataType>> sourceType = context.getSourceDataType();
            Operation sourceOp = context.getSourceOperation();
            boolean sourceWrapped = sourceOp != null && sourceOp.isOutputWrapperStyle() && sourceOp.getOutputWrapper() != null;
            boolean sourceNotSubjectToWrapping = sourceOp != null && sourceOp.isNotSubjectToWrapping();

            WrapperHandler sourceWrapperHandler = null;
            String sourceDataBinding = getDataBinding(sourceOp);
            sourceWrapperHandler = getWrapperHandler(sourceDataBinding, sourceWrapped);

            DataType<List<DataType>> targetType = context.getTargetDataType();
            Operation targetOp = (Operation)context.getTargetOperation();
            boolean targetWrapped = targetOp != null && targetOp.isOutputWrapperStyle() && targetOp.getOutputWrapper() != null;
            boolean targetNotSubjectToWrapping = targetOp != null && targetOp.isNotSubjectToWrapping();

            WrapperHandler targetWrapperHandler = null;
            String targetDataBinding = getDataBinding(targetOp);
            targetWrapperHandler = getWrapperHandler(targetDataBinding, targetWrapped);      

            if ((!sourceWrapped &&!sourceNotSubjectToWrapping) && targetWrapped) {
                // Unwrapped --> Wrapped
                WrapperInfo wrapper = targetOp.getOutputWrapper();
                ElementInfo wrapperElement = wrapper.getWrapperElement();
                List<ElementInfo> childElements = wrapper.getChildElements();
                Class<?> targetWrapperClass = wrapper != null ? wrapper.getWrapperClass() : null;

                Object[] outputs = null;            
                if ( !sourceOp.hasArrayWrappedOutput() ) {
                    outputs = new Object[] {response};
                } else {
                    outputs = (Object[])response;
                }      
                
                // If the source can be wrapped, wrapped it first
                if (sourceWrapperHandler != null) {
                    WrapperInfo sourceWrapperInfo = sourceOp.getOutputWrapper();
                    DataType sourceWrapperType =
                        sourceWrapperInfo != null ? sourceWrapperInfo.getWrapperType() : null;

                    if (sourceWrapperType != null && matches(sourceOp.getOutputWrapper(), targetOp.getOutputWrapper())) {
                        Class<?> sourceWrapperClass = sourceWrapperType.getPhysical();

                        Object sourceWrapper = sourceWrapperHandler.create(sourceOp, false);
                        if (sourceWrapper != null) {
                            if (!childElements.isEmpty()) {
                                // Set the return value
                                sourceWrapperHandler.setChildren(sourceWrapper,
                                                                 outputs,
                                                                 sourceOp,
                                                                 false);
                            }
                            Object targetWrapper =
                                mediator.mediate(sourceWrapper, sourceWrapperType, targetType.getLogical().get(0), context
                                    .getMetadata());
                            return targetWrapper;
                        }
                    }
                }
                Object targetWrapper = targetWrapperHandler.create(targetOp, false);

                if (childElements.isEmpty()) {
                    // void output
                    return targetWrapper;
                }

                // No source wrapper, so we want to transform the child and then wrap the child-level target with the
                // target wrapper handler.
                
                Object[] targetChildren = new Object[outputs.length];
                for (int i = 0; i < outputs.length; i++) {
                    DataType<XMLType> targetOutputType = wrapper.getUnwrappedType().getLogical().get(i);
                    targetChildren[i] =
                        mediator.mediate(outputs[i], sourceType.getLogical().get(i), targetOutputType, context.getMetadata());
                }
                targetWrapperHandler.setChildren(targetWrapper,
                                                 targetChildren,
                                                 targetOp,
                                                 false);
                return targetWrapper;                                
                
            } else if (sourceWrapped && (!targetWrapped && !targetNotSubjectToWrapping)) {
                // Wrapped to Unwrapped
                Object sourceWrapper = response;
                List<ElementInfo> childElements = sourceOp.getOutputWrapper().getChildElements();
                if (childElements.isEmpty()) {
                    // The void output
                    return null;
                }
                if (targetWrapperHandler != null) {
                    ElementInfo wrapperElement = sourceOp.getOutputWrapper().getWrapperElement();

                    // FIXME: This is a workaround for the wsdless support as it passes in child elements
                    // under the wrapper that only matches by position
                    if (sourceWrapperHandler.isInstance(sourceWrapper, sourceOp, false)) {

                        WrapperInfo targetWrapperInfo = targetOp.getOutputWrapper();
                        DataType targetWrapperType =
                            targetWrapperInfo != null ? targetWrapperInfo.getWrapperType() : null;

                        if (targetWrapperType != null && matches(sourceOp.getOutputWrapper(), targetOp.getOutputWrapper())) {
                            Object targetWrapper =
                                mediator.mediate(sourceWrapper, sourceType.getLogical().get(0), targetWrapperType, context
                                    .getMetadata());
                            List targetChildren = targetWrapperHandler.getChildren(targetWrapper, targetOp, false);
                            if (targetOp.hasArrayWrappedOutput()) {
                                return targetChildren.toArray();
                            } else {
                                return targetChildren.get(0);
                            }
                        }
                    }
                }
                
                // Otherwise we need to unwrap on the source side, and then transform each child                
                Object[] sourceChildren = sourceWrapperHandler.getChildren(sourceWrapper, sourceOp, false).toArray();
                Object[] target = new Object[sourceChildren.length];
                for (int i = 0; i < sourceChildren.length; i++) {
                    DataType<XMLType> childType = sourceOp.getOutputWrapper().getUnwrappedType().getLogical().get(i);
                    target[i] =
                        mediator.mediate(sourceChildren[i], childType, targetType.getLogical().get(i), context
                            .getMetadata());
                }

                if (targetOp.hasArrayWrappedOutput()) {
                    return target;
                } else {
                    if (target.length > 1 ) {
                        throw new IllegalStateException("Expecting only one output based on Operation model, found: " + 
                                                        target.length + " # of outputs.");
                    }
                    return target[0];
                }
            } else {                
                Object[] outputs = null;            
                if ( !sourceOp.hasArrayWrappedOutput() ) {
                    outputs = new Object[] {response};
                } else {
                    outputs = (Object[])response;
                }      
                Object[] target = new Object[outputs.length];
                for (int i = 0; i < outputs.length; i++) {
                    Object child =
                        mediator.mediate(outputs[i], sourceType.getLogical().get(i), targetType.getLogical().get(i), context
                            .getMetadata());
                    target[i] = child;
                }                
                if (targetOp.hasArrayWrappedOutput()) {
                    return target;
                } else {
                    if (target.length > 1 ) {
                        throw new IllegalStateException("Expecting only one output based on Operation model, found: " + 
                                                        target.length + " # of outputs.");
                    }
                    return target[0];
                }
            }
        } catch (Exception e) {
            throw new TransformationException(e);
        }
    }