/* * Copyright (c) 1998-2011 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * * Free Software Foundation, Inc. * 59 Temple Place, Suite 330 * Boston, MA 02111-1307 USA * * @author Scott Ferguson */ package com.caucho.quercus.marshal; import com.caucho.quercus.env.*; import com.caucho.quercus.module.ModuleContext; import com.caucho.quercus.lib.file.BinaryInput; import com.caucho.quercus.lib.file.BinaryOutput; import com.caucho.quercus.lib.regexp.Ereg; import com.caucho.quercus.lib.regexp.Eregi; import com.caucho.quercus.lib.regexp.Regexp; import com.caucho.quercus.lib.regexp.UnicodeEreg; import com.caucho.quercus.lib.regexp.UnicodeEregi; import com.caucho.quercus.program.JavaClassDef; import com.caucho.util.L10N; import com.caucho.vfs.Path; import java.io.InputStream; import java.math.BigDecimal; import java.math.BigInteger; import java.net.URL; import java.util.Calendar; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Code for marshaling (PHP to Java) and unmarshaling (Java to PHP) arguments. */ public class MarshalFactory { private static final HashMap<Class<?>,Marshal> _marshalMap = new HashMap<Class<?>,Marshal>(); protected ModuleContext _moduleContext; public MarshalFactory(ModuleContext moduleContext) { _moduleContext = moduleContext; } public Marshal create(Class<?> argType) { return create(argType, false); } public Marshal create(Class<?> argType, boolean isNotNull) { return create(argType, isNotNull, false); } public Marshal create(Class<?> argType, boolean isNotNull, boolean isNullAsFalse) { Marshal marshal; marshal = _marshalMap.get(argType); // optimized cases, new types should be added to JavaMarshal // XXX: put the static classes in _marshalMap if (marshal != null) { } else if (boolean.class.equals(argType)) { marshal = BooleanMarshal.MARSHAL; } else if (Boolean.class.equals(argType)) { marshal = BooleanObjectMarshal.MARSHAL; } else if (byte.class.equals(argType)) { marshal = ByteMarshal.MARSHAL; } else if (Byte.class.equals(argType)) { marshal = ByteObjectMarshal.MARSHAL; } else if (short.class.equals(argType)) { marshal = ShortMarshal.MARSHAL; } else if (Short.class.equals(argType)) { marshal = ShortObjectMarshal.MARSHAL; } else if (int.class.equals(argType)) { marshal = IntegerMarshal.MARSHAL; } else if (Integer.class.equals(argType)) { marshal = IntegerObjectMarshal.MARSHAL; } else if (long.class.equals(argType)) { marshal = LongMarshal.MARSHAL; } else if (Long.class.equals(argType)) { marshal = LongObjectMarshal.MARSHAL; } else if (LongValue.class.equals(argType)) { marshal = LongValueMarshal.MARSHAL; } else if (float.class.equals(argType)) { marshal = FloatMarshal.MARSHAL; } else if (Float.class.equals(argType)) { marshal = FloatObjectMarshal.MARSHAL; } else if (double.class.equals(argType)) { marshal = DoubleMarshal.MARSHAL; } else if (Double.class.equals(argType)) { marshal = DoubleObjectMarshal.MARSHAL; } else if (DoubleValue.class.equals(argType)) { marshal = DoubleValueMarshal.MARSHAL; } else if (BigDecimal.class.equals(argType)) { marshal = BigDecimalMarshal.MARSHAL; } else if (BigInteger.class.equals(argType)) { marshal = BigIntegerMarshal.MARSHAL; } else if (char.class.equals(argType)) { marshal = CharacterMarshal.MARSHAL; } else if (Character.class.equals(argType)) { marshal = CharacterObjectMarshal.MARSHAL; } else if (Path.class.equals(argType)) { marshal = PathMarshal.MARSHAL; } else if (StringValue.class.equals(argType)) { marshal = StringValueMarshal.MARSHAL; } else if (UnicodeValue.class.equals(argType)) { marshal = UnicodeValueMarshal.MARSHAL; } else if (BinaryValue.class.equals(argType)) { marshal = BinaryValueMarshal.MARSHAL; } else if (BinaryBuilderValue.class.equals(argType)) { marshal = BinaryValueMarshal.MARSHAL; } else if (InputStream.class.equals(argType)) { marshal = InputStreamMarshal.MARSHAL; } else if (BinaryInput.class.equals(argType)) { marshal = BinaryInputMarshal.MARSHAL; } else if (BinaryOutput.class.equals(argType)) { marshal = BinaryOutputMarshal.MARSHAL; } else if (ArrayValue.class.equals(argType)) { marshal = ArrayValueMarshal.MARSHAL; } else if (Value.class.equals(argType)) { marshal = ValueMarshal.MARSHAL; } else if (Value.class.isAssignableFrom(argType)) { marshal = new ExtValueMarshal(argType); } else if (void.class.equals(argType)) { marshal = VoidMarshal.MARSHAL; } else if (Calendar.class.equals(argType)) { marshal = CalendarMarshal.MARSHAL; } else if (Date.class.equals(argType)) { marshal = DateMarshal.MARSHAL; } else if (Regexp.class.equals(argType)) { marshal = RegexpMarshal.MARSHAL; } else if (Regexp[].class.equals(argType)) { marshal = RegexpArrayMarshal.MARSHAL; } else if (Ereg.class.equals(argType)) { marshal = EregMarshal.MARSHAL; } else if (Eregi.class.equals(argType)) { marshal = EregiMarshal.MARSHAL; } else if (UnicodeEreg.class.equals(argType)) { marshal = UnicodeEregMarshal.MARSHAL; } else if (UnicodeEregi.class.equals(argType)) { marshal = UnicodeEregiMarshal.MARSHAL; } else if (URL.class.equals(argType)) { marshal = URLMarshal.MARSHAL; } else if (byte[].class.equals(argType)) { marshal = JavaByteArrayMarshal.MARSHAL; } else if (char[].class.equals(argType)) { marshal = JavaCharacterArrayMarshal.MARSHAL; } else if (argType.isArray()) { marshal = new JavaArrayMarshal(argType); } else if (Map.class.isAssignableFrom(argType)) { String typeName = argType.getName(); JavaClassDef javaDef = _moduleContext.getJavaClassDefinition(typeName); marshal = new JavaMapMarshal(javaDef, isNotNull, isNullAsFalse); } else if (List.class.isAssignableFrom(argType)) { String typeName = argType.getName(); JavaClassDef javaDef = _moduleContext.getJavaClassDefinition(typeName); marshal = new JavaListMarshal(javaDef, isNotNull, isNullAsFalse); } else if (Collection.class.isAssignableFrom(argType)) { String typeName = argType.getName(); JavaClassDef javaDef = _moduleContext.getJavaClassDefinition(typeName); marshal = new JavaCollectionMarshal(javaDef, isNotNull, isNullAsFalse); } else if (Enum.class.isAssignableFrom(argType)) { marshal = new EnumMarshal(argType); } else { String typeName = argType.getName(); JavaClassDef javaDef = _moduleContext.getJavaClassDefinition(typeName); marshal = new JavaMarshal(javaDef, isNotNull, isNullAsFalse); } if (!isNullAsFalse) return marshal; else { if (Value.class.equals(argType) || Boolean.class.equals(argType) || Byte.class.equals(argType) || Short.class.equals(argType) || Integer.class.equals(argType) || Long.class.equals(argType) || Float.class.equals(argType) || Double.class.equals(argType) || Character.class.equals(argType)) { String shortName = argType.getSimpleName(); throw new UnsupportedOperationException( "@ReturnNullAsFalse cannot be used with return type `" + shortName + "'"); } return new NullAsFalseMarshal(marshal); } } public Marshal createReference() { return ReferenceMarshal.MARSHAL; } public Marshal createValuePassThru() { return ValueMarshal.MARSHAL_PASS_THRU; } public Marshal createExpectString() { return ExpectMarshal.MARSHAL_EXPECT_STRING; } public Marshal createExpectNumeric() { return ExpectMarshal.MARSHAL_EXPECT_NUMERIC; } public Marshal createExpectBoolean() { return ExpectMarshal.MARSHAL_EXPECT_BOOLEAN; } static { _marshalMap.put(String.class, StringMarshal.MARSHAL); _marshalMap.put(Callable.class, CallableMarshal.MARSHAL); _marshalMap.put(Class.class, ClassMarshal.MARSHAL); } }