alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (AbstractListField.java)

This example Java source code file (AbstractListField.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

abstractfield, abstractlistfield, accessor, cpropertyinfo, jblock, jclass, jexpression, jfieldref, jfieldvar, jmethod, jprimitivetype, jtype, util

The AbstractListField.java Java example source code

/*
 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

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

import java.util.List;

import com.sun.codemodel.internal.JBlock;
import com.sun.codemodel.internal.JClass;
import com.sun.codemodel.internal.JExpr;
import com.sun.codemodel.internal.JExpression;
import com.sun.codemodel.internal.JFieldRef;
import com.sun.codemodel.internal.JFieldVar;
import com.sun.codemodel.internal.JMethod;
import com.sun.codemodel.internal.JMod;
import com.sun.codemodel.internal.JOp;
import com.sun.codemodel.internal.JPrimitiveType;
import com.sun.codemodel.internal.JType;
import com.sun.tools.internal.xjc.generator.bean.ClassOutlineImpl;
import com.sun.tools.internal.xjc.model.CPropertyInfo;

/**
 * Common code for property renderer that generates a List as
 * its underlying data structure.
 *
 * <p>
 * For performance reasons, the actual list object used to store
 * data is lazily created.
 *
 * @author
 *     Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
 */
abstract class AbstractListField extends AbstractField {
    /** The field that stores the list. */
    protected JFieldVar field;

    /**
     * a method that lazily initializes a List.
     * Lazily created.
     *
     * [RESULT]
     * List _getFoo() {
     *   if(field==null)
     *     field = create new list;
     *   return field;
     * }
     */
    private JMethod internalGetter;

    /**
     * If this collection property is a collection of a primitive type,
     * this variable refers to that primitive type.
     * Otherwise null.
     */
    protected final JPrimitiveType primitiveType;

    protected final JClass listT = codeModel.ref(List.class).narrow(exposedType.boxify());

    /**
     * True to create a new instance of List eagerly in the constructor.
     * False otherwise.
     *
     * <p>
     * Setting it to true makes the generated code slower (as more list instances need to be
     * allocated), but it works correctly if the user specifies the custom type of a list.
     */
    private final boolean eagerInstanciation;

    /**
     * Call {@link #generate()} method right after this.
     */
    protected AbstractListField(ClassOutlineImpl outline, CPropertyInfo prop, boolean eagerInstanciation) {
        super(outline,prop);
        this.eagerInstanciation = eagerInstanciation;

        if( implType instanceof JPrimitiveType ) {
            // primitive types don't have this tricky distinction
            assert implType==exposedType;
            primitiveType = (JPrimitiveType)implType;
        } else
            primitiveType = null;
    }

    protected final void generate() {

        // for the collectionType customization to take effect, the field needs to be strongly typed,
        // not just List<Foo>.
        field = outline.implClass.field( JMod.PROTECTED, listT, prop.getName(false) );
        if(eagerInstanciation)
            field.init(newCoreList());

        annotate(field);

        // generate the rest of accessors
        generateAccessors();
    }

    private void generateInternalGetter() {
        internalGetter = outline.implClass.method(JMod.PROTECTED,listT,"_get"+prop.getName(true));
        if(!eagerInstanciation) {
            // if eagerly instanciated, the field can't be null
            fixNullRef(internalGetter.body());
        }
        internalGetter.body()._return(field);
    }

    /**
     * Generates statement(s) so that the successive {@link Accessor#ref(boolean)} with
     * true will always return a non-null list.
     *
     * This is useful to avoid generating redundant internal getter.
     */
    protected final void fixNullRef(JBlock block) {
        block._if(field.eq(JExpr._null()))._then()
            .assign(field,newCoreList());
    }

    public JType getRawType() {
        return codeModel.ref(List.class).narrow(exposedType.boxify());
    }

    private JExpression newCoreList() {
        return JExpr._new(getCoreListType());
    }

    /**
     * Concrete class that implements the List interface.
     * Used as the actual data storage.
     */
    protected abstract JClass getCoreListType();


    /** Generates accessor methods. */
    protected abstract void generateAccessors();



    /**
     *
     *
     * @author
     *     Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
     */
    protected abstract class Accessor extends AbstractField.Accessor {

        /**
         * Reference to the {@link AbstractListField#field}
         * of the target object.
         */
        protected final JFieldRef field;

        protected Accessor( JExpression $target ) {
            super($target);
            field = $target.ref(AbstractListField.this.field);
        }


        protected final JExpression unbox( JExpression exp ) {
            if(primitiveType==null) return exp;
            else                    return primitiveType.unwrap(exp);
        }
        protected final JExpression box( JExpression exp ) {
            if(primitiveType==null) return exp;
            else                    return primitiveType.wrap(exp);
        }

        /**
         * Returns a reference to the List field that stores the data.
         * <p>
         * Using this method hides the fact that the list is lazily
         * created.
         *
         * @param canBeNull
         *      if true, the returned expression may be null (this is
         *      when the list is still not constructed.) This could be
         *      useful when the caller can deal with null more efficiently.
         *      When the list is null, it should be treated as if the list
         *      is empty.
         *
         *      if false, the returned expression will never be null.
         *      This is the behavior users would see.
         */
        protected final JExpression ref(boolean canBeNull) {
            if(canBeNull)
                return field;
            if(internalGetter==null)
                generateInternalGetter();
            return $target.invoke(internalGetter);
        }

        public JExpression count() {
            return JOp.cond( field.eq(JExpr._null()), JExpr.lit(0), field.invoke("size") );
        }

        public void unsetValues( JBlock body ) {
            body.assign(field,JExpr._null());
        }
        public JExpression hasSetValue() {
            return field.ne(JExpr._null()).cand(field.invoke("isEmpty").not());
        }
    }

}

Other Java examples (source code examples)

Here is a short list of links related to this Java AbstractListField.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.