001: /*
002: * Copyright 2005 Joe Walker
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.directwebremoting.convert;
017:
018: import java.lang.reflect.Array;
019: import java.util.ArrayList;
020: import java.util.List;
021: import java.util.StringTokenizer;
022:
023: import org.apache.commons.logging.Log;
024: import org.apache.commons.logging.LogFactory;
025: import org.directwebremoting.dwrp.ArrayJsonOutboundVariable;
026: import org.directwebremoting.dwrp.ArrayNonJsonOutboundVariable;
027: import org.directwebremoting.dwrp.ErrorOutboundVariable;
028: import org.directwebremoting.dwrp.CollectionOutboundVariable;
029: import org.directwebremoting.dwrp.ParseUtil;
030: import org.directwebremoting.dwrp.ProtocolConstants;
031: import org.directwebremoting.extend.Converter;
032: import org.directwebremoting.extend.ConverterManager;
033: import org.directwebremoting.extend.InboundContext;
034: import org.directwebremoting.extend.InboundVariable;
035: import org.directwebremoting.extend.MarshallException;
036: import org.directwebremoting.extend.OutboundContext;
037: import org.directwebremoting.extend.OutboundVariable;
038: import org.directwebremoting.util.LocalUtil;
039:
040: /**
041: * An implementation of Converter for Arrays.
042: * @author Joe Walker [joe at getahead dot ltd dot uk]
043: * @noinspection RefusedBequest
044: */
045: public class ArrayConverter extends BaseV20Converter implements
046: Converter {
047: /* (non-Javadoc)
048: * @see org.directwebremoting.convert.BaseV20Converter#setConverterManager(org.directwebremoting.ConverterManager)
049: */
050: @Override
051: public void setConverterManager(ConverterManager converterManager) {
052: this .converterManager = converterManager;
053: }
054:
055: /* (non-Javadoc)
056: * @see org.directwebremoting.Converter#convertInbound(java.lang.Class, org.directwebremoting.InboundVariable, org.directwebremoting.InboundContext)
057: */
058: public Object convertInbound(Class<?> paramType,
059: InboundVariable data, InboundContext inctx)
060: throws MarshallException {
061: if (!paramType.isArray()) {
062: throw new MarshallException(paramType);
063: }
064:
065: String value = data.getValue();
066: if (value.startsWith(ProtocolConstants.INBOUND_ARRAY_START)) {
067: value = value.substring(1);
068: }
069: if (value.endsWith(ProtocolConstants.INBOUND_ARRAY_END)) {
070: value = value.substring(0, value.length() - 1);
071: }
072:
073: StringTokenizer st = new StringTokenizer(value,
074: ProtocolConstants.INBOUND_ARRAY_SEPARATOR);
075: int size = st.countTokens();
076:
077: Class<?> componentType = paramType.getComponentType();
078: //componentType = LocalUtil.getNonPrimitiveType(componentType);
079: Object array = Array.newInstance(componentType, size);
080:
081: // We should put the new object into the working map in case it
082: // is referenced later nested down in the conversion process.
083: inctx.addConverted(data, paramType, array);
084: InboundContext incx = data.getLookup();
085:
086: for (int i = 0; i < size; i++) {
087: String token = st.nextToken();
088: String[] split = ParseUtil.splitInbound(token);
089: String splitType = split[LocalUtil.INBOUND_INDEX_TYPE];
090: String splitValue = split[LocalUtil.INBOUND_INDEX_VALUE];
091:
092: InboundVariable nested = new InboundVariable(incx, null,
093: splitType, splitValue);
094: nested.dereference();
095: Object output = converterManager.convertInbound(
096: componentType, nested, inctx, inctx
097: .getCurrentTypeHintContext());
098: Array.set(array, i, output);
099: }
100:
101: return array;
102: }
103:
104: /* (non-Javadoc)
105: * @see org.directwebremoting.Converter#convertOutbound(java.lang.Object, org.directwebremoting.OutboundContext)
106: */
107: public OutboundVariable convertOutbound(Object data,
108: OutboundContext outctx) throws MarshallException {
109: if (!data.getClass().isArray()) {
110: throw new MarshallException(data.getClass());
111: }
112:
113: CollectionOutboundVariable ov;
114:
115: // Stash this bit of data to cope with recursion
116: if (outctx.isJsonMode()) {
117: ov = new ArrayJsonOutboundVariable();
118: } else {
119: ov = new ArrayNonJsonOutboundVariable(outctx);
120: }
121: outctx.put(data, ov);
122:
123: // Convert all the data members
124: int size = Array.getLength(data);
125: List<OutboundVariable> ovs = new ArrayList<OutboundVariable>();
126: for (int i = 0; i < size; i++) {
127: OutboundVariable nested;
128: try {
129: nested = converterManager.convertOutbound(Array.get(
130: data, i), outctx);
131: } catch (Exception ex) {
132: String errorMessage = "Conversion error for "
133: + data.getClass().getName() + ".";
134: log.warn(errorMessage, ex);
135:
136: nested = new ErrorOutboundVariable(errorMessage);
137: }
138: ovs.add(nested);
139: }
140:
141: // Group the list of converted objects into this OutboundVariable
142: ov.setChildren(ovs);
143:
144: return ov;
145: }
146:
147: /**
148: * The log stream
149: */
150: private static final Log log = LogFactory
151: .getLog(ArrayConverter.class);
152:
153: /**
154: * The converter manager to which we forward array members for conversion
155: */
156: private ConverterManager converterManager = null;
157: }
|