001: /*
002: * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.tools.internal.xjc.generator.bean.field;
027:
028: import java.util.List;
029:
030: import com.sun.codemodel.internal.JBlock;
031: import com.sun.codemodel.internal.JConditional;
032: import com.sun.codemodel.internal.JExpr;
033: import com.sun.codemodel.internal.JExpression;
034: import com.sun.codemodel.internal.JMethod;
035: import com.sun.codemodel.internal.JType;
036: import com.sun.codemodel.internal.JVar;
037: import com.sun.tools.internal.xjc.generator.bean.ClassOutlineImpl;
038: import com.sun.tools.internal.xjc.generator.bean.MethodWriter;
039: import com.sun.tools.internal.xjc.model.CPropertyInfo;
040: import com.sun.tools.internal.xjc.outline.FieldAccessor;
041: import com.sun.xml.internal.bind.api.impl.NameConverter;
042:
043: /**
044: * Realizes a property through one getter and one setter.
045: * This renders:
046: *
047: * <pre>
048: * T' field;
049: * T getXXX() { ... }
050: * void setXXX(T value) { ... }
051: * </pre>
052: *
053: * <p>
054: * Normally T'=T, but under some tricky circumstances they could be different
055: * (like T'=Integer, T=int.)
056: *
057: * This realization is only applicable to fields with (1,1)
058: * or (0,1) multiplicity.
059: *
060: * @author
061: * Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
062: */
063: public class SingleField extends AbstractFieldWithVar {
064:
065: protected SingleField(ClassOutlineImpl context, CPropertyInfo prop) {
066: this (context, prop, false);
067: }
068:
069: /**
070: *
071: * @param forcePrimitiveAccess
072: * forces the setter/getter to expose the primitive type.
073: * it's a pointless customization, but it's nevertheless in the spec.
074: */
075: protected SingleField(ClassOutlineImpl context, CPropertyInfo prop,
076: boolean forcePrimitiveAccess) {
077: super (context, prop);
078: assert !exposedType.isPrimitive() && !implType.isPrimitive();
079:
080: createField();
081:
082: MethodWriter writer = context.createMethodWriter();
083: NameConverter nc = context.parent().getModel()
084: .getNameConverter();
085:
086: // [RESULT]
087: // Type getXXX() {
088: // #ifdef default value
089: // if(value==null)
090: // return defaultValue;
091: // #endif
092: // return value;
093: // }
094: JExpression defaultValue = null;
095: if (prop.defaultValue != null)
096: defaultValue = prop.defaultValue.compute(outline.parent());
097:
098: // if Type is a wrapper and we have a default value,
099: // we can use the primitive type.
100: JType getterType;
101: if (defaultValue != null || forcePrimitiveAccess)
102: getterType = exposedType.unboxify();
103: else
104: getterType = exposedType;
105:
106: JMethod $get = writer.declareMethod(getterType,
107: getGetterMethod());
108: String javadoc = prop.javadoc;
109: if (javadoc.length() == 0)
110: javadoc = Messages.DEFAULT_GETTER_JAVADOC.format(nc
111: .toVariableName(prop.getName(true)));
112: writer.javadoc().append(javadoc);
113:
114: if (defaultValue == null) {
115: $get.body()._return(ref());
116: } else {
117: JConditional cond = $get.body()
118: ._if(ref().eq(JExpr._null()));
119: cond._then()._return(defaultValue);
120: cond._else()._return(ref());
121: }
122:
123: List<Object> possibleTypes = listPossibleTypes(prop);
124: writer.javadoc().addReturn().append("possible object is\n")
125: .append(possibleTypes);
126:
127: // [RESULT]
128: // void setXXX(Type newVal) {
129: // this.value = newVal;
130: // }
131: JMethod $set = writer.declareMethod(codeModel.VOID, "set"
132: + prop.getName(true));
133: JType setterType = exposedType;
134: if (forcePrimitiveAccess)
135: setterType = setterType.unboxify();
136: JVar $value = writer.addParameter(setterType, "value");
137: JBlock body = $set.body();
138: body.assign(JExpr._this ().ref(ref()), castToImplType($value));
139:
140: javadoc = prop.javadoc;
141: if (javadoc.length() == 0)
142: javadoc = Messages.DEFAULT_SETTER_JAVADOC.format(nc
143: .toVariableName(prop.getName(true)));
144: writer.javadoc().append(javadoc);
145: writer.javadoc().addParam($value).append("allowed object is\n")
146: .append(possibleTypes);
147: }
148:
149: public final JType getFieldType() {
150: return implType;
151: }
152:
153: public FieldAccessor create(JExpression targetObject) {
154: return new Accessor(targetObject);
155: }
156:
157: protected class Accessor extends AbstractFieldWithVar.Accessor {
158: protected Accessor(JExpression $target) {
159: super ($target);
160: }
161:
162: public void unsetValues(JBlock body) {
163: body.assign($ref, JExpr._null());
164: }
165:
166: public JExpression hasSetValue() {
167: return $ref.ne(JExpr._null());
168: }
169: }
170: }
|