All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.tools.xjc.generator.bean.field.ArrayField Maven / Gradle / Ivy

There is a newer version: 4.0.5
Show newest version
/*
 * Copyright (c) 1997, 2023 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0, which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

package com.sun.tools.xjc.generator.bean.field;

import com.sun.codemodel.JAssignmentTarget;
import java.util.List;
import com.sun.codemodel.JBlock;
import com.sun.codemodel.JClass;
import com.sun.codemodel.JExpr;
import com.sun.codemodel.JExpression;
import com.sun.codemodel.JForLoop;
import com.sun.codemodel.JMethod;
import com.sun.codemodel.JMod;
import com.sun.codemodel.JOp;
import com.sun.codemodel.JType;
import com.sun.codemodel.JVar;
import com.sun.tools.xjc.generator.bean.ClassOutlineImpl;
import com.sun.tools.xjc.generator.bean.MethodWriter;
import com.sun.tools.xjc.model.CPropertyInfo;

/**
 * Realizes a property as an "indexed property"
 * as specified in the JAXB spec.
 *
 * 

* We will generate the following set of methods: *

 * T[] getX();
 * T getX( int idx );
 * void setX(T[] values);
 * void setX( int idx, T value );
 * 
* * We still use List as our back storage. * This renderer also handles boxing/unboxing if * T is a boxed type. * * @author * Kohsuke Kawaguchi ([email protected]) */ final class ArrayField extends AbstractListField { class Accessor extends AbstractListField.Accessor { protected Accessor( JExpression $target ) { super($target); } public void toRawValue(JBlock block, JVar $var) { block.assign($var,$target.invoke($getAll)); } public void fromRawValue(JBlock block, String uniqueName, JExpression $var) { block.invoke($target,$setAll).arg($var); } @Override public JExpression hasSetValue() { return field.ne(JExpr._null()).cand(field.ref("length").gt(JExpr.lit(0))); } } private JMethod $setAll; private JMethod $getAll; ArrayField(ClassOutlineImpl context, CPropertyInfo prop) { super(context,prop,false); generateArray(); } protected final void generateArray() { field = outline.implClass.field( JMod.PROTECTED, getCoreListType(), prop.getName(false) ); annotate(field); // generate the rest of accessors generateAccessors(); } public void generateAccessors() { MethodWriter writer = outline.createMethodWriter(); Accessor acc = create(JExpr._this()); JVar $idx,$value; JBlock body; // [RESULT] T[] getX() { // if( ==null ) return new T[0]; // T[] retVal = new T[this._return.length] ; // System.arraycopy(this._return, 0, "retVal", 0, this._return.length); // return (retVal); // } $getAll = writer.declareMethod( exposedType.array(),"get"+prop.getName(true)); if (prop.javadoc != null && prop.javadoc.length() > 0) { writer.javadoc().append(prop.javadoc).append("\n\n"); } body = $getAll.body(); body._if( acc.ref(true).eq(JExpr._null()) )._then() ._return(JExpr.newArray(exposedType,0)); JVar var = body.decl(exposedType.array(), "retVal", JExpr.newArray(implType,acc.ref(true).ref("length"))); body.add(codeModel.ref(System.class).staticInvoke("arraycopy") .arg(acc.ref(true)).arg(JExpr.lit(0)) .arg(var) .arg(JExpr.lit(0)).arg(acc.ref(true).ref("length"))); body._return(JExpr.direct("retVal")); List returnTypes = listPossibleTypes(prop); writer.javadoc().addReturn().append("array of\n").append(returnTypes); // [RESULT] // ET getX(int idx) { // if( ==null ) throw new IndexOutOfBoundsException(); // return unbox(.get(idx)); // } JMethod $get = writer.declareMethod(exposedType,"get"+prop.getName(true)); $idx = writer.addParameter(codeModel.INT,"idx"); $get.body()._if(acc.ref(true).eq(JExpr._null()))._then() ._throw(JExpr._new(codeModel.ref(IndexOutOfBoundsException.class))); writer.javadoc().append(prop.javadoc); $get.body()._return(acc.ref(true).component($idx)); writer.javadoc().addReturn().append("one of\n").append(returnTypes); // [RESULT] int getXLength() { // if( ==null ) throw new IndexOutOfBoundsException(); // return .length; // } JMethod $getLength = writer.declareMethod(codeModel.INT,"get"+prop.getName(true)+"Length"); $getLength.body()._if(acc.ref(true).eq(JExpr._null()))._then() ._return(JExpr.lit(0)); $getLength.body()._return(acc.ref(true).ref("length")); // [RESULT] void setX(ET[] values) { // if (values == null) { // = null; // return; // } // int len = values.length; // for( int i=0; i[i] = values[i]; // } $setAll = writer.declareMethod( codeModel.VOID, "set"+prop.getName(true)); writer.javadoc().append(prop.javadoc); $value = writer.addParameter(exposedType.array(),"values"); $setAll.body()._if( $value.eq(JExpr._null()) )._then() .assign((JAssignmentTarget) acc.ref(true), JExpr._null()) ._return(); JVar $len = $setAll.body().decl(codeModel.INT,"len", $value.ref("length")); $setAll.body().assign( (JAssignmentTarget) acc.ref(true), castToImplTypeArray(JExpr.newArray( implType, $len))); JForLoop _for = $setAll.body()._for(); JVar $i = _for.init( codeModel.INT, "i", JExpr.lit(0) ); _for.test( JOp.lt($i,$len) ); _for.update( $i.incr() ); _for.body().assign(acc.ref(true).component($i), castToImplType(acc.box($value.component($i)))); writer.javadoc().addParam($value) .append("allowed objects are\n") .append(returnTypes); // [RESULT] ET setX(int idx, ET value) // [idx] = value JMethod $set = writer.declareMethod( exposedType, "set"+prop.getName(true)); $idx = writer.addParameter( codeModel.INT, "idx" ); $value = writer.addParameter( exposedType, "value" ); writer.javadoc().append(prop.javadoc); body = $set.body(); body._return( JExpr.assign(acc.ref(true).component($idx), castToImplType(acc.box($value)))); writer.javadoc().addParam($value) .append("allowed object is\n") .append(returnTypes); } @Override public JType getRawType() { return exposedType.array(); } protected JClass getCoreListType() { return exposedType.array(); } public Accessor create(JExpression targetObject) { return new Accessor(targetObject); } /** * Case from {@link #exposedType} to array of {@link #implType} . */ protected final JExpression castToImplTypeArray( JExpression exp ) { return JExpr.cast(implType.array(), exp); } }