001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019package lucee.runtime.net.rpc; 020 021import java.io.IOException; 022import java.math.BigDecimal; 023import java.net.MalformedURLException; 024import java.util.ArrayList; 025import java.util.Calendar; 026import java.util.Date; 027import java.util.HashMap; 028import java.util.HashSet; 029import java.util.Iterator; 030import java.util.List; 031import java.util.Map; 032import java.util.Map.Entry; 033import java.util.Set; 034import java.util.TimeZone; 035import java.util.Vector; 036 037import javax.xml.namespace.QName; 038import javax.xml.rpc.encoding.TypeMapping; 039 040import lucee.commons.lang.ClassException; 041import lucee.commons.lang.ClassUtil; 042import lucee.commons.lang.ExceptionUtil; 043import lucee.commons.lang.Pair; 044import lucee.commons.lang.PhysicalClassLoader; 045import lucee.commons.lang.StringUtil; 046import lucee.runtime.Component; 047import lucee.runtime.ComponentScope; 048import lucee.runtime.ComponentSpecificAccess; 049import lucee.runtime.PageContext; 050import lucee.runtime.component.Property; 051import lucee.runtime.component.PropertyImpl; 052import lucee.runtime.engine.ThreadLocalPageContext; 053import lucee.runtime.exp.ApplicationException; 054import lucee.runtime.exp.ExpressionException; 055import lucee.runtime.exp.PageException; 056import lucee.runtime.interpreter.CFMLExpressionInterpreter; 057import lucee.runtime.net.http.ReqRspUtil; 058import lucee.runtime.op.Caster; 059import lucee.runtime.op.Decision; 060import lucee.runtime.op.date.DateCaster; 061import lucee.runtime.reflection.Reflector; 062import lucee.runtime.type.Array; 063import lucee.runtime.type.Collection; 064import lucee.runtime.type.Collection.Key; 065import lucee.runtime.type.KeyImpl; 066import lucee.runtime.type.ObjectWrap; 067import lucee.runtime.type.Query; 068import lucee.runtime.type.QueryColumn; 069import lucee.runtime.type.QueryImpl; 070import lucee.runtime.type.Struct; 071import lucee.runtime.type.StructImpl; 072import lucee.runtime.type.dt.DateTime; 073import lucee.runtime.type.dt.TimeSpan; 074import lucee.runtime.type.scope.Argument; 075import lucee.runtime.type.util.ArrayUtil; 076import lucee.runtime.type.util.ComponentProUtil; 077import lucee.runtime.type.util.ComponentUtil; 078 079import org.apache.axis.Constants; 080import org.apache.axis.types.Day; 081import org.apache.axis.types.Duration; 082import org.apache.axis.types.Entities; 083import org.apache.axis.types.Entity; 084import org.apache.axis.types.Language; 085import org.apache.axis.types.Month; 086import org.apache.axis.types.MonthDay; 087import org.apache.axis.types.NCName; 088import org.apache.axis.types.NMToken; 089import org.apache.axis.types.NMTokens; 090import org.apache.axis.types.Name; 091import org.apache.axis.types.Token; 092import org.apache.axis.types.URI; 093import org.apache.axis.types.URI.MalformedURIException; 094import org.apache.axis.types.Year; 095import org.apache.axis.types.YearMonth; 096import org.apache.axis.wsdl.symbolTable.TypeEntry; 097 098import coldfusion.xml.rpc.QueryBean; 099 100/** 101 * Axis Type Caster 102 */ 103public final class AxisCaster { 104 105 /** 106 * cast a value to a Axis Compatible Type 107 * @param type 108 * @param value 109 * @return Axis Compatible Type 110 * @throws PageException 111 */ 112 public static Object toAxisType(TypeMapping tm,TimeZone tz,TypeEntry typeEntry,QName type, Object value) throws PageException { 113 return _toAxisType(tm, tz, typeEntry,type,null, value,new HashSet<Object>()); 114 } 115 116 public static Object toAxisType(TypeMapping tm,Object value, Class targetClass) throws PageException { 117 return _toAxisType(tm,null,null,null,targetClass, value, new HashSet<Object>()); 118 } 119 120 /** 121 * cast a value to a Axis Compatible Type 122 * @param type 123 * @param value 124 * @return Axis Compatible Type 125 * @throws PageException 126 */ 127 private static Object _toAxisType(TypeMapping tm,TimeZone tz,TypeEntry typeEntry,QName type, Class targetClass, Object value,Set<Object> done) throws PageException { 128 129 // first make sure we have no wrapper 130 if(value instanceof ObjectWrap) { 131 value=((ObjectWrap)value).getEmbededObject(); 132 } 133 134 135 if(done.contains(value)){ 136 return null;// TODO not sure what in this case is the best solution. 137 } 138 139 done.add(value); 140 try{ 141 if(type!=null) { 142 143 // Array Of 144 if(type.getLocalPart().startsWith("ArrayOf")) { 145 return toArray(tm,typeEntry,type,value,done); 146 } 147 148 149 // XSD 150 for(int i=0;i<Constants.URIS_SCHEMA_XSD.length;i++) { 151 if(Constants.URIS_SCHEMA_XSD[i].equals(type.getNamespaceURI())) { 152 return toAxisTypeXSD(tm,tz,type.getLocalPart(), value,done); 153 } 154 } 155 if(StringUtil.startsWithIgnoreCase(type.getLocalPart(),"xsd_")) { 156 return toAxisTypeXSD(tm,tz,type.getLocalPart().substring(4), value,done); 157 } 158 159 //SOAP 160 if(type.getNamespaceURI().indexOf("soap")!=-1) { 161 return toAxisTypeSoap(tm,type.getLocalPart(), value,done); 162 } 163 if(StringUtil.startsWithIgnoreCase(type.getLocalPart(),"soap_")) { 164 return toAxisTypeSoap(tm,type.getLocalPart().substring(5), value,done); 165 } 166 } 167 return _toDefinedType(tm,typeEntry,type,targetClass,value,done); 168 169 } 170 finally{ 171 done.remove(value); 172 } 173 } 174 175 private static Object toArray(TypeMapping tm, TypeEntry typeEntry,QName type, Object value, Set<Object> done) throws PageException { 176 if(type==null || !type.getLocalPart().startsWith("ArrayOf")) 177 throw new ApplicationException("invalid call of the functionn toArray"); 178 179 // get component Type 180 String tmp = type.getLocalPart().substring(7); 181 QName componentType=null; 182 183 // no arrayOf embeded anymore 184 if(tmp.indexOf("ArrayOf")==-1 && typeEntry!=null) { 185 TypeEntry ref = typeEntry.getRefType(); 186 componentType=ref.getQName(); 187 } 188 if(componentType==null) { 189 if(tmp.startsWith("_tns1_"))tmp=tmp.substring(6); 190 componentType=new QName(type.getNamespaceURI(), tmp); 191 } 192 Object[] objs = Caster.toNativeArray(value); 193 Object[] rtns; 194 List<Object> list=new ArrayList<Object>(); 195 196 197 Class componentClass=null; 198 Object v; 199 for(int i=0;i<objs.length;i++) { 200 v=_toAxisType(tm,null,typeEntry,componentType,null,objs[i],done); 201 list.add(v); 202 if(i==0) { 203 if(v!=null) componentClass=v.getClass(); 204 } 205 else { 206 if(v==null || v.getClass()!=componentClass) componentClass=null; 207 } 208 209 } 210 211 if(componentClass!=null) { 212 componentClass=toAxisTypeClass(componentClass); 213 rtns = (Object[]) java.lang.reflect.Array.newInstance(componentClass, objs.length); 214 } 215 else 216 rtns = new Object[objs.length]; 217 218 219 220 return list.toArray(rtns); 221 } 222 223 224 225 226 private static Object toAxisTypeSoap(TypeMapping tm,String local, Object value, Set<Object> done) throws PageException { 227 if(local.equals(Constants.SOAP_ARRAY.getLocalPart())) return toArrayList(tm,value,done); 228 if(local.equals(Constants.SOAP_ARRAY12.getLocalPart())) return toArrayList(tm,value,done); 229 if(local.equals(Constants.SOAP_ARRAY_ATTRS11.getLocalPart())) return toArrayList(tm,value,done); 230 if(local.equals(Constants.SOAP_ARRAY_ATTRS12.getLocalPart())) return toArrayList(tm,value,done); 231 if(local.equals(Constants.SOAP_BASE64.getLocalPart())) return Caster.toBinary(value); 232 if(local.equals(Constants.SOAP_BASE64BINARY.getLocalPart())) return Caster.toBinary(value); 233 if(local.equals(Constants.SOAP_BOOLEAN.getLocalPart())) return Caster.toBoolean(value); 234 if(local.equals(Constants.SOAP_BYTE.getLocalPart())) return Caster.toByte(value); 235 if(local.equals(Constants.SOAP_DECIMAL.getLocalPart())) return new BigDecimal(Caster.toDoubleValue(value)); 236 if(local.equals(Constants.SOAP_DOUBLE.getLocalPart())) return Caster.toDouble(value); 237 if(local.equals(Constants.SOAP_FLOAT.getLocalPart())) return new Float(Caster.toDoubleValue(value)); 238 if(local.equals(Constants.SOAP_INT.getLocalPart())) return Caster.toInteger(value); 239 if(local.equals(Constants.SOAP_INTEGER.getLocalPart())) return Caster.toInteger(value); 240 if(local.equals(Constants.SOAP_LONG.getLocalPart())) return Caster.toLong(value); 241 if(local.equals(Constants.SOAP_MAP.getLocalPart())) return toMap(tm,value,done); 242 if(local.equals(Constants.SOAP_SHORT.getLocalPart())) return Caster.toShort(value); 243 if(local.equals(Constants.SOAP_STRING.getLocalPart())) return Caster.toString(value); 244 if(local.equals(Constants.SOAP_VECTOR.getLocalPart())) return toVector(tm,value,done); 245 246 return _toDefinedType(tm,null,null,null,value,done); 247 248 249 } 250 251 private static Object toAxisTypeXSD(TypeMapping tm,TimeZone tz,String local, Object value, Set<Object> done) throws PageException { 252 //if(local.equals(Constants.XSD_ANY.getLocalPart())) return value; 253 if(local.equalsIgnoreCase(Constants.XSD_ANYSIMPLETYPE.getLocalPart())) return Caster.toString(value); 254 if(local.equalsIgnoreCase(Constants.XSD_ANYURI.getLocalPart())) return toURI(value); 255 if(local.equalsIgnoreCase(Constants.XSD_STRING.getLocalPart())) return Caster.toString(value); 256 if(local.equalsIgnoreCase(Constants.XSD_BASE64.getLocalPart())) return Caster.toBinary(value); 257 if(local.equalsIgnoreCase(Constants.XSD_BOOLEAN.getLocalPart())) return Caster.toBoolean(value); 258 if(local.equalsIgnoreCase(Constants.XSD_BYTE.getLocalPart())) return Caster.toByte(value); 259 if(local.equalsIgnoreCase(Constants.XSD_DATE.getLocalPart())) return Caster.toDate(value,null); 260 if(local.equalsIgnoreCase(Constants.XSD_DATETIME.getLocalPart())) return Caster.toDate(value,null); 261 if(local.equalsIgnoreCase(Constants.XSD_DAY.getLocalPart())) return toDay(value); 262 if(local.equalsIgnoreCase(Constants.XSD_DECIMAL.getLocalPart())) return new BigDecimal(Caster.toDoubleValue(value)); 263 if(local.equalsIgnoreCase(Constants.XSD_DOUBLE.getLocalPart())) return Caster.toDouble(value); 264 if(local.equalsIgnoreCase(Constants.XSD_DURATION.getLocalPart())) return toDuration(value); 265 if(local.equalsIgnoreCase(Constants.XSD_ENTITIES.getLocalPart())) return toEntities(value); 266 if(local.equalsIgnoreCase(Constants.XSD_ENTITY.getLocalPart())) return toEntity(value); 267 if(local.equalsIgnoreCase(Constants.XSD_FLOAT.getLocalPart())) return new Float(Caster.toDoubleValue(value)); 268 if(local.equalsIgnoreCase(Constants.XSD_HEXBIN.getLocalPart())) return Caster.toBinary(value); 269 if(local.equalsIgnoreCase(Constants.XSD_ID.getLocalPart())) return Caster.toString(value); 270 if(local.equalsIgnoreCase(Constants.XSD_IDREF.getLocalPart())) return Caster.toString(value); 271 if(local.equalsIgnoreCase(Constants.XSD_IDREFS.getLocalPart())) return Caster.toString(value); 272 if(local.equalsIgnoreCase(Constants.XSD_INT.getLocalPart())) return Caster.toInteger(value); 273 if(local.equalsIgnoreCase(Constants.XSD_INTEGER.getLocalPart())) return Caster.toInteger(value); 274 if(local.equalsIgnoreCase(Constants.XSD_LANGUAGE.getLocalPart())) return toLanguage(value); 275 if(local.equalsIgnoreCase(Constants.XSD_LONG.getLocalPart())) return Caster.toLong(value); 276 if(local.equalsIgnoreCase(Constants.XSD_MONTH.getLocalPart())) return toMonth(value); 277 if(local.equalsIgnoreCase(Constants.XSD_MONTHDAY.getLocalPart())) return toMonthDay(value); 278 if(local.equalsIgnoreCase(Constants.XSD_NAME.getLocalPart())) return toName(value); 279 if(local.equalsIgnoreCase(Constants.XSD_NCNAME.getLocalPart())) return toNCName(value); 280 if(local.equalsIgnoreCase(Constants.XSD_NEGATIVEINTEGER.getLocalPart())) return Caster.toInteger(value); 281 if(local.equalsIgnoreCase(Constants.XSD_NMTOKEN.getLocalPart())) return toNMToken(value); 282 if(local.equalsIgnoreCase(Constants.XSD_NMTOKENS.getLocalPart())) return toNMTokens(value); 283 if(local.equalsIgnoreCase(Constants.XSD_NONNEGATIVEINTEGER.getLocalPart())) return Caster.toInteger(value); 284 if(local.equalsIgnoreCase(Constants.XSD_NONPOSITIVEINTEGER.getLocalPart())) return Caster.toInteger(value); 285 if(local.equalsIgnoreCase(Constants.XSD_NORMALIZEDSTRING.getLocalPart())) return Caster.toString(value); 286 if(local.equalsIgnoreCase(Constants.XSD_POSITIVEINTEGER.getLocalPart())) return Caster.toInteger(value); 287 if(local.equalsIgnoreCase(Constants.XSD_QNAME.getLocalPart())) return toQName(value); 288 if(local.equalsIgnoreCase(Constants.XSD_SCHEMA.getLocalPart())) return toQName(value); 289 if(local.equalsIgnoreCase(Constants.XSD_SHORT.getLocalPart())) return Caster.toShort(value); 290 if(local.equalsIgnoreCase(Constants.XSD_TIME.getLocalPart())) return DateCaster.toTime(tz,value); 291 if(local.equalsIgnoreCase(Constants.XSD_TIMEINSTANT1999.getLocalPart())) return DateCaster.toTime(tz,value); 292 if(local.equalsIgnoreCase(Constants.XSD_TIMEINSTANT2000.getLocalPart())) return DateCaster.toTime(tz,value); 293 if(local.equalsIgnoreCase(Constants.XSD_TOKEN.getLocalPart())) return toToken(value); 294 if(local.equalsIgnoreCase(Constants.XSD_UNSIGNEDBYTE.getLocalPart())) return Caster.toByte(value); 295 if(local.equalsIgnoreCase(Constants.XSD_UNSIGNEDINT.getLocalPart())) return Caster.toInteger(value); 296 if(local.equalsIgnoreCase(Constants.XSD_UNSIGNEDLONG.getLocalPart())) return Caster.toLong(value); 297 if(local.equalsIgnoreCase(Constants.XSD_UNSIGNEDSHORT.getLocalPart())) return Caster.toShort(value); 298 if(local.equalsIgnoreCase(Constants.XSD_YEAR.getLocalPart())) return toYear(value); 299 if(local.equalsIgnoreCase(Constants.XSD_YEARMONTH.getLocalPart())) return toYearMonth(value); 300 return _toDefinedType(tm, null,null,null, value, done); 301 } 302 303 private static ArrayList<Object> toArrayList(TypeMapping tm,Object value, Set<Object> done) throws PageException { 304 Array arr = Caster.toArray(value); 305 ArrayList<Object> al=new ArrayList<Object>(); 306 int len=arr.size(); 307 Object o; 308 for(int i=0;i<len;i++) { 309 o=arr.get(i+1,null); 310 al.add(i,_toAxisType(tm,null,null,null,null,o,done)); 311 } 312 return al; 313 } 314 315 private static Object[] toNativeArray(TypeMapping tm,Class targetClass,Object value, Set<Object> done) throws PageException { 316 Object[] objs = Caster.toNativeArray(value); 317 Object[] rtns; 318 319 Class<?> componentClass = null; 320 if(targetClass!=null) { 321 componentClass = targetClass.getComponentType(); 322 } 323 324 if(componentClass!=null) { 325 componentClass=toAxisTypeClass(componentClass); 326 rtns = (Object[]) java.lang.reflect.Array.newInstance(componentClass, objs.length); 327 } 328 else 329 rtns = new Object[objs.length]; 330 331 try{ 332 for(int i=0;i<objs.length;i++) { 333 rtns[i]=_toAxisType(tm,null,null,null,componentClass,objs[i],done); 334 } 335 } 336 // just in case something goes wrong with typed array 337 catch(ArrayStoreException ase){ 338 rtns = new Object[objs.length]; 339 for(int i=0;i<objs.length;i++) { 340 rtns[i]=_toAxisType(tm,null,null,null,componentClass,objs[i],done); 341 } 342 } 343 344 return rtns; 345 } 346 347 private static Vector<Object> toVector(TypeMapping tm,Object value, Set<Object> done) throws PageException { 348 Array arr = Caster.toArray(value); 349 Vector<Object> v=new Vector<Object>(); 350 int len=arr.size(); 351 Object o; 352 for(int i=0;i<len;i++) { 353 o=arr.get(i+1,null); 354 v.set(i,_toAxisType(tm,null,null,null,null,o,done)); 355 } 356 return v; 357 } 358 359 public static Component toComponent(PageContext pc, Pojo pojo, String compPath , Component defaultValue) { 360 try { 361 Component cfc = pc.loadComponent(compPath); 362 Property[] props = ComponentProUtil.getProperties(cfc, false, true, false, false); 363 PojoIterator it=new PojoIterator(pojo); 364 // only when the same amount of properties 365 if(props.length==it.size()) { 366 Map<Collection.Key, Property> propMap = toMap(props); 367 Property p; 368 Pair<Collection.Key,Object> pair; 369 ComponentScope scope = cfc.getComponentScope(); 370 while(it.hasNext()){ 371 pair=it.next(); 372 p=propMap.get(pair.getName()); 373 if(p==null) return defaultValue; 374 Object val = null; 375 try { 376 val = Caster.castTo(pc, p.getType(), pair.getValue(), false); 377 } catch (PageException e) { } 378 379 // store in variables and this scope 380 scope.setEL(pair.getName(), val); 381 cfc.setEL(pair.getName(), val); 382 } 383 return cfc; 384 } 385 } 386 catch (PageException e) {} 387 return defaultValue; 388 } 389 390 private static Map<Collection.Key,Property> toMap(Property[] props) { 391 Map<Collection.Key,Property> map=new HashMap<Collection.Key, Property>(); 392 for(int i=0;i<props.length;i++){ 393 map.put(KeyImpl.init(props[i].getName()), props[i]); 394 } 395 return map; 396 } 397 398 public static Pojo toPojo(Pojo pojo, TypeMapping tm,TypeEntry typeEntry,QName type,Component comp, Set<Object> done) throws PageException { 399 PageContext pc = ThreadLocalPageContext.get(); 400 try { 401 return _toPojo(pc,pojo, tm,typeEntry,type, comp,done); 402 } 403 catch (Exception e) { 404 throw Caster.toPageException(e); 405 } 406 } 407 408 private static Pojo _toPojo(PageContext pc, Pojo pojo, TypeMapping tm,TypeEntry typeEntry,QName type,Component comp, Set<Object> done) throws PageException {//print.ds();System.exit(0); 409 comp=ComponentSpecificAccess.toComponentSpecificAccess(Component.ACCESS_PRIVATE,comp); 410 ComponentScope scope = comp.getComponentScope(); 411 412 // create Pojo 413 if(pojo==null) { 414 try { 415 pojo = (Pojo) ClassUtil.loadInstance(ComponentUtil.getComponentPropertiesClass(pc,comp)); 416 } catch (ClassException e) { 417 throw Caster.toPageException(e); 418 } 419 } 420 421 // initialize Pojo 422 Property[] props=ComponentProUtil.getProperties(comp, false, true, false, false); 423 _initPojo(pc,typeEntry,type,pojo,props,scope,comp,tm,done); 424 425 return pojo; 426 } 427 428 public static Pojo toPojo(Pojo pojo, TypeMapping tm,TypeEntry typeEntry,QName type,Struct sct, Set<Object> done) throws PageException { 429 PageContext pc = ThreadLocalPageContext.get(); 430 try { 431 return _toPojo(pc,pojo, tm,typeEntry,type, sct,done); 432 } 433 catch (Exception e) { 434 throw Caster.toPageException(e); 435 } 436 } 437 438 private static Pojo _toPojo(PageContext pc, Pojo pojo, TypeMapping tm,TypeEntry typeEntry,QName type,Struct sct, Set<Object> done) throws PageException {//print.ds();System.exit(0); 439 if(pojo==null) { 440 try { 441 PhysicalClassLoader cl=(PhysicalClassLoader) pc.getConfig().getRPCClassLoader(false); 442 pojo = (Pojo) ClassUtil.loadInstance(ComponentUtil.getStructPropertiesClass(pc,sct,cl)); 443 } 444 catch (ClassException e) { 445 throw Caster.toPageException(e); 446 } 447 catch (IOException e) { 448 throw Caster.toPageException(e); 449 } 450 } 451 452 // initialize 453 List<Property> props=new ArrayList<Property>(); 454 Iterator<Entry<Key, Object>> it = sct.entryIterator(); 455 Entry<Key, Object> e; 456 PropertyImpl p; 457 while(it.hasNext()){ 458 e = it.next(); 459 p=new PropertyImpl(); 460 p.setAccess(Component.ACCESS_PUBLIC); 461 p.setName(e.getKey().getString()); 462 p.setType(e.getValue()==null?"any":Caster.toTypeName(e.getValue())); 463 props.add(p); 464 } 465 466 _initPojo(pc,typeEntry,type,pojo,props.toArray(new Property[props.size()]),sct,null,tm,done); 467 468 return pojo; 469 } 470 471 private static void _initPojo(PageContext pc, TypeEntry typeEntry, QName type, Pojo pojo, Property[] props, Struct sct, Component comp, TypeMapping tm, Set<Object> done) throws PageException { 472 Property p; 473 Object v; 474 Collection.Key k; 475 CFMLExpressionInterpreter interpreter = new CFMLExpressionInterpreter(false); 476 477 478 479 for(int i=0;i<props.length;i++){ 480 p=props[i]; 481 k=Caster.toKey(p.getName()); 482 // value 483 v=sct.get(k,null); 484 if(v==null && comp!=null)v=comp.get(k, null); 485 486 // default 487 488 if(v!=null)v=Caster.castTo(pc, p.getType(), v, false); 489 else{ 490 if(!StringUtil.isEmpty(p.getDefault())){ 491 try { 492 v=Caster.castTo(pc, p.getType(), p.getDefault(), false); 493 494 } 495 catch(PageException pe) { 496 try { 497 v=interpreter.interpret(pc, p.getDefault()); 498 v=Caster.castTo(pc, p.getType(), v, false); 499 } 500 catch(PageException pe2) { 501 throw new ExpressionException("can not use default value ["+p.getDefault()+"] for property ["+p.getName()+"] with type ["+p.getType()+"]"); 502 } 503 } 504 } 505 } 506 507 // set or throw 508 if(v==null) { 509 if(p.isRequired())throw new ExpressionException("required property ["+p.getName()+"] is not defined"); 510 } 511 else { 512 TypeEntry childTE=null; 513 QName childT=null; 514 if(typeEntry!=null) { 515 childTE = AxisUtil.getContainedElement(typeEntry,p.getName(),null); 516 if(childTE!=null) childT=childTE.getQName(); 517 518 } 519 Reflector.callSetter(pojo, p.getName().toLowerCase(), _toAxisType(tm,null,childTE,childT,null,v,done)); 520 } 521 } 522 } 523 524 private static QueryBean toQueryBean(TypeMapping tm,Object value, Set<Object> done) throws PageException { 525 Query query = Caster.toQuery(value); 526 int recordcount=query.getRecordcount(); 527 String[] columnList = query.getColumns(); 528 QueryColumn[] columns=new QueryColumn[columnList.length]; 529 Object[][] data = new Object[recordcount][columnList.length]; 530 531 for(int i=0;i<columnList.length;i++) { 532 columns[i]=query.getColumn(columnList[i]); 533 } 534 535 int row; 536 for(row=1;row<=recordcount;row++) { 537 for(int i=0;i<columns.length;i++) { 538 data[row-1][i]=_toAxisType(tm,null,null,null,null,columns[i].get(row,null),done); 539 } 540 } 541 542 QueryBean qb = new QueryBean(); 543 qb.setColumnList(columnList); 544 qb.setData(data); 545 return qb; 546 547 } 548 549 550 551 private static Map<String,Object> toMap(TypeMapping tm,Object value, Set<Object> done) throws PageException { 552 Struct src = Caster.toStruct(value); 553 554 HashMap<String,Object> trg=new HashMap<String,Object>(); 555 Iterator<Entry<Key, Object>> it = src.entryIterator(); 556 Entry<Key, Object> e; 557 while(it.hasNext()) { 558 e = it.next(); 559 trg.put(e.getKey().getString(),_toAxisType(tm,null,null,null,null,e.getValue(),done)); 560 561 } 562 return trg; 563 564 } 565 566 private static Object _toDefinedType(TypeMapping tm,TypeEntry typeEntry,QName type,Class targetClass,Object value,Set<Object> done) throws PageException { 567 568 // Date 569 if(value instanceof Date) {// not set to Decision.isDate(value) 570 return new Date(((Date)value).getTime()); 571 } 572 573 574 575 576 Class clazz=type==null?null:((org.apache.axis.encoding.TypeMapping)tm).getClassForQName(type); 577 // Pojo 578 if(clazz!=null && Reflector.isInstaneOf(clazz,Pojo.class)) { 579 Pojo pojo; 580 try{ 581 pojo=(Pojo) ClassUtil.loadInstance(clazz); 582 } 583 catch(Throwable t){ 584 ExceptionUtil.rethrowIfNecessary(t); 585 throw Caster.toPageException(t); 586 } 587 // Struct 588 if(Decision.isStruct(value)) { 589 590 if(value instanceof Component) 591 return toPojo(pojo,tm,typeEntry,type,(Component)value,done); 592 return toPojo(pojo,tm,typeEntry,type,Caster.toStruct(value),done); 593 } 594 } 595 596 // No Mapping found 597 598 599 // Array 600 if(Decision.isArray(value) && !(value instanceof Argument)) { 601 if(value instanceof byte[]) return value; 602 return toNativeArray(tm,targetClass,value,done); 603 } 604 // Struct 605 if(Decision.isStruct(value)) { 606 if(value instanceof Component) { 607 Object pojo= toPojo(null,tm,null,null,(Component)value,done); 608 try { 609 if(type==null || type.getLocalPart().equals("anyType")) { 610 type= new QName(getRequestDefaultNameSpace(),pojo.getClass().getName()); 611 //type= new QName(getRequestNameSpace(),pojo.getClass().getName()); 612 //print.ds("missing type for "+pojo.getClass().getName()); 613 } 614 TypeMappingUtil.registerBeanTypeMapping(tm, pojo.getClass(), type); 615 616 } 617 catch(Throwable fault){ 618 ExceptionUtil.rethrowIfNecessary(fault); 619 throw Caster.toPageException(fault); 620 } 621 return pojo; 622 } 623 /*if(type!=null && !type.getLocalPart().equals("anyType")) { 624 Object pojo= toPojo(null,tm,Caster.toStruct(value),targetClass,done); 625 626 //Map<String, Object> map = toMap(tm,value,targetClass,done); 627 //TypeMappingUtil.registerMapTypeMapping(tm, map.getClass(), type); 628 TypeMappingUtil.registerBeanTypeMapping(tm, pojo.getClass(), type); 629 return pojo; 630 }*/ 631 return toMap(tm,value,done); 632 633 634 } 635 // Query 636 if(Decision.isQuery(value)) return toQueryBean(tm,value,done); 637 // Other 638 return value; 639 } 640 641 public static Class toAxisTypeClass(Class clazz) { 642 if(clazz.isArray()) { 643 return ClassUtil.toArrayClass(toAxisTypeClass(clazz.getComponentType())); 644 } 645 646 if(Query.class==clazz) return QueryBean.class; 647 if(Array.class==clazz) return Object[].class; 648 if(Struct.class==clazz) return Map.class; 649 //if(Struct[].class==clazz) return Map[].class; 650 //if(Query[].class==clazz) return QueryBean[].class; 651 652 return clazz; 653 } 654 655 private static Object toURI(Object value) throws PageException { 656 if(value instanceof URI) return value; 657 if(value instanceof java.net.URI) return value; 658 try { 659 return new URI(Caster.toString(value)); 660 } catch (MalformedURIException e) { 661 throw Caster.toPageException(e); 662 } 663 } 664 665 private static Token toToken(Object value) throws PageException { 666 if(value instanceof Token) return (Token) value; 667 return new Token(Caster.toString(value)); 668 } 669 670 private static QName toQName(Object value) throws PageException { 671 if(value instanceof QName) return (QName) value; 672 return new QName(Caster.toString(value)); 673 } 674 675 private static NMTokens toNMTokens(Object value) throws PageException { 676 if(value instanceof NMTokens) return (NMTokens) value; 677 return new NMTokens(Caster.toString(value)); 678 } 679 680 private static NMToken toNMToken(Object value) throws PageException { 681 if(value instanceof NMToken) return (NMToken) value; 682 return new NMToken(Caster.toString(value)); 683 } 684 private static NCName toNCName(Object value) throws PageException { 685 if(value instanceof NCName) return (NCName) value; 686 return new NCName(Caster.toString(value)); 687 } 688 689 private static Name toName(Object value) throws PageException { 690 if(value instanceof Name) return (Name) value; 691 return new Name(Caster.toString(value)); 692 } 693 694 private static Language toLanguage(Object value) throws PageException { 695 if(value instanceof Language) return (Language) value; 696 return new Language(Caster.toString(value)); 697 } 698 699 private static Entities toEntities(Object value) throws PageException { 700 if(value instanceof Entities) return (Entities) value; 701 return new Entities(Caster.toString(value)); 702 } 703 704 private static Entity toEntity(Object value) throws PageException { 705 if(value instanceof Entity) return (Entity) value; 706 return new Entity(Caster.toString(value)); 707 } 708 709 private static Day toDay(Object value) throws PageException { 710 if(value instanceof Day) return (Day) value; 711 if(Decision.isDateSimple(value,false)) { 712 return new Day(Caster.toDate(value,null).getDate()); 713 } 714 715 try { 716 return new Day(Caster.toIntValue(value)); 717 } 718 catch (Exception e) { 719 try { 720 return new Day(Caster.toString(value)); 721 } catch (NumberFormatException nfe) { 722 throw Caster.toPageException(nfe); 723 } 724 catch (ExpressionException ee) { 725 throw ee; 726 } 727 } 728 } 729 730 private static Year toYear(Object value) throws PageException { 731 if(value instanceof Year) return (Year) value; 732 if(Decision.isDateSimple(value,false)) { 733 return new Year(Caster.toDate(value,null).getYear()); 734 } 735 try { 736 return new Year(Caster.toIntValue(value)); 737 } 738 catch (Exception e) { 739 try { 740 return new Year(Caster.toString(value)); 741 } catch (NumberFormatException nfe) { 742 throw Caster.toPageException(nfe); 743 } 744 catch (ExpressionException ee) { 745 throw ee; 746 } 747 } 748 } 749 750 private static Month toMonth(Object value) throws PageException { 751 if(value instanceof Month) return (Month) value; 752 if(Decision.isDateSimple(value,false)) { 753 return new Month(Caster.toDate(value,null).getMonth()); 754 } 755 try { 756 return new Month(Caster.toIntValue(value)); 757 } 758 catch (Exception e) { 759 try { 760 return new Month(Caster.toString(value)); 761 } catch (NumberFormatException nfe) { 762 throw Caster.toPageException(nfe); 763 } 764 catch (ExpressionException ee) { 765 throw ee; 766 } 767 } 768 } 769 770 private static YearMonth toYearMonth(Object value) throws PageException { 771 if(value instanceof YearMonth) return (YearMonth) value; 772 if(Decision.isDateSimple(value,false)) { 773 DateTime dt = Caster.toDate(value,null); 774 return new YearMonth(dt.getYear(),dt.getMonth()); 775 } 776 777 try { 778 return new YearMonth(Caster.toString(value)); 779 } catch (NumberFormatException nfe) { 780 throw Caster.toPageException(nfe); 781 } 782 catch (ExpressionException ee) { 783 throw ee; 784 } 785 } 786 787 private static MonthDay toMonthDay(Object value) throws PageException { 788 if(value instanceof MonthDay) return (MonthDay) value; 789 if(Decision.isDateSimple(value,false)) { 790 DateTime dt = Caster.toDate(value,null); 791 return new MonthDay(dt.getMonth(),dt.getDate()); 792 } 793 794 try { 795 return new MonthDay(Caster.toString(value)); 796 } catch (NumberFormatException nfe) { 797 throw Caster.toPageException(nfe); 798 } 799 catch (ExpressionException ee) { 800 throw ee; 801 } 802 } 803 804 private static Duration toDuration(Object value) throws PageException, IllegalArgumentException { 805 if(value instanceof Duration) return (Duration) value; 806 try { 807 TimeSpan ts = Caster.toTimespan(value); 808 return new Duration(true, 0, 0, ts.getDay(), ts.getHour(), ts.getMinute(), ts.getSecond()); 809 } catch (PageException e) { 810 return new Duration(Caster.toString(value)); 811 } 812 } 813 814 815 public static Object toLuceeType(PageContext pc, Object value) throws PageException { 816 return toLuceeType(pc, null, value); 817 } 818 819 820 public static Object toLuceeType(PageContext pc, String customType, Object value) throws PageException { 821 pc=ThreadLocalPageContext.get(pc); 822 if(pc!=null && value instanceof Pojo) { 823 if(!StringUtil.isEmpty(customType)){ 824 Component cfc = toComponent(pc, (Pojo)value,customType, null); 825 if(cfc!=null) return cfc; 826 } 827 /* 828 // try package/class name as component name 829 String compPath=value.getClass().getName(); 830 Component cfc = toComponent(pc, (Pojo)value, compPath, null); 831 if(cfc!=null) return cfc; 832 833 // try class name as component name 834 compPath=ListUtil.last(compPath, '.'); 835 cfc = toComponent(pc, (Pojo)value, compPath, null); 836 if(cfc!=null) return cfc; 837 */ 838 } 839 if(value instanceof Date || value instanceof Calendar) {// do not change to caster.isDate 840 return Caster.toDate(value,null); 841 } 842 if(value instanceof Object[]) { 843 Object[] arr=(Object[]) value; 844 if(!ArrayUtil.isEmpty(arr)){ 845 boolean allTheSame=true; 846 // byte 847 if(arr[0] instanceof Byte){ 848 for(int i=1;i<arr.length;i++){ 849 if(!(arr[i] instanceof Byte)){ 850 allTheSame=false; 851 break; 852 } 853 } 854 if(allTheSame){ 855 byte[] bytes=new byte[arr.length]; 856 for(int i=0;i<arr.length;i++){ 857 bytes[i]=Caster.toByteValue(arr[i]); 858 } 859 return bytes; 860 } 861 } 862 } 863 } 864 if(value instanceof Byte[]) { 865 Byte[] arr=(Byte[]) value; 866 if(!ArrayUtil.isEmpty(arr)){ 867 byte[] bytes=new byte[arr.length]; 868 for(int i=0;i<arr.length;i++){ 869 bytes[i]=arr[i].byteValue(); 870 } 871 return bytes; 872 } 873 } 874 if(value instanceof byte[]) { 875 return value; 876 } 877 if(Decision.isArray(value)) { 878 879 Array a = Caster.toArray(value); 880 int len=a.size(); 881 Object o; 882 String ct; 883 for(int i=1;i<=len;i++) { 884 o=a.get(i,null); 885 if(o!=null) { 886 ct=customType!=null && customType.endsWith("[]")?customType.substring(0,customType.length()-2):null; 887 a.setEL(i,toLuceeType(pc,ct,o)); 888 } 889 } 890 return a; 891 } 892 if(value instanceof Map) { 893 Struct sct = new StructImpl(); 894 Iterator it=((Map)value).entrySet().iterator(); 895 Map.Entry entry; 896 while(it.hasNext()) { 897 entry=(Entry) it.next(); 898 sct.setEL(Caster.toString(entry.getKey()),toLuceeType(pc,null,entry.getValue())); 899 } 900 return sct; 901 902 903 //return StructUtil.copyToStruct((Map)value); 904 } 905 if(isQueryBean(value)) { 906 QueryBean qb = (QueryBean) value; 907 String[] strColumns = qb.getColumnList(); 908 Object[][] data = qb.getData(); 909 int recorcount=data.length; 910 Query qry=new QueryImpl(strColumns,recorcount,"QueryBean"); 911 QueryColumn[] columns=new QueryColumn[strColumns.length]; 912 for(int i=0;i<columns.length;i++) { 913 columns[i]=qry.getColumn(strColumns[i]); 914 } 915 916 int row; 917 for(row=1;row<=recorcount;row++) { 918 for(int i=0;i<columns.length;i++) { 919 columns[i].set(row,toLuceeType(pc,null,data[row-1][i])); 920 } 921 } 922 return qry; 923 } 924 if(Decision.isQuery(value)) { 925 Query q = Caster.toQuery(value); 926 int recorcount=q.getRecordcount(); 927 String[] strColumns = q.getColumns(); 928 929 QueryColumn col; 930 int row; 931 for(int i=0;i<strColumns.length;i++) { 932 col=q.getColumn(strColumns[i]); 933 for(row=1;row<=recorcount;row++) { 934 col.set(row,toLuceeType(pc,null,col.get(row,null))); 935 } 936 } 937 return q; 938 } 939 return value; 940 } 941 942 private static boolean isQueryBean(Object value) { 943 return (value instanceof QueryBean); 944 } 945 946 public static QName toComponentType(QName qName, QName defaultValue) { 947 String lp = qName.getLocalPart(); 948 String uri = qName.getNamespaceURI(); 949 if(lp.startsWith("ArrayOf")) 950 return new QName(uri, lp.substring(7)); 951 return defaultValue; 952 } 953 954 public static String getRequestNameSpace() { 955 String rawURL = ReqRspUtil.getRequestURL(ThreadLocalPageContext.get().getHttpServletRequest(),false); 956 String urlPath =""; 957 try { 958 urlPath = new java.net.URL(rawURL).getPath(); 959 } 960 catch (MalformedURLException e) {} 961 String pathWithoutContext = urlPath.replaceFirst("/[^/]*", ""); 962 963 964 return "http://rpc.xml.coldfusion" + pathWithoutContext.toLowerCase(); 965 } 966 public static String getRequestDefaultNameSpace() { 967 return "http://rpc.xml.coldfusion"; 968 } 969 970}