001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.visualweb.insync.beans;
042:
043: import java.beans.PropertyDescriptor;
044:
045: import org.netbeans.modules.visualweb.extension.openide.util.Trace;
046: import org.netbeans.modules.visualweb.insync.java.JavaClass;
047: import org.netbeans.modules.visualweb.insync.java.Statement;
048:
049: /**
050: * Representation of a single property setting on our parent bean, which maps to a single property
051: * setter statement in the init block.
052: */
053: public class Property extends BeansNode {
054:
055: public static final Property[] EMPTY_ARRAY = {};
056:
057: // General property fields
058: final Bean bean; // owning bean
059: final PropertyDescriptor descriptor;
060:
061: // Java source-based property fields
062: private JavaClass javaClass;
063: private Statement stmt;
064:
065: private String valueSource;
066: private Object value;
067: private boolean inserted;
068:
069: //--------------------------------------------------------------------------------- Construction
070:
071: /**
072: * Partially construct a property to be fully populated later
073: * @param beansUnit
074: * @param bean
075: * @param name
076: */
077: protected Property(Bean bean, PropertyDescriptor descriptor,
078: boolean unused) {
079: super (bean.getUnit());
080: this .bean = bean;
081: //this.name = name;
082: this .descriptor = descriptor;
083: javaClass = unit.getThisClass();
084: }
085:
086: /**
087: * Construct a property bound to existing statement & its bean. Called only from factory method
088: * below.
089: * @param beansUnit
090: */
091: private Property(Bean bean, PropertyDescriptor descriptor,
092: Statement stmt, Object/*ExpressionTree*/valueExpr) {
093: this (bean, descriptor, false);
094: this .stmt = stmt;
095: assert Trace.trace("insync.beans", "P new bound Property: "
096: + this );
097: }
098:
099: /**
100: * Create a property setting bound to a specific statement
101: * @param unit
102: * @param s
103: * @return the new bound property if bindable, else null
104: */
105: static protected Property newBoundInstance(BeansUnit unit,
106: Statement stmt) {
107: Bean bean = unit.getBean(stmt.getBeanName());
108: if (bean == null) {
109: return null;
110: }
111: PropertyDescriptor pd = bean
112: .getPropertyDescriptorForSetter(stmt
113: .getPropertySetterName());
114: if (pd == null) {
115: return null;
116: }
117:
118: Property prop = new Property(bean, pd, stmt, null);
119: prop.setInserted(true);
120: return prop;
121: }
122:
123: /**
124: * Construct a new property, creating the underlying statement methods
125: * @param bean
126: * @param descriptor
127: */
128: protected Property(Bean bean, PropertyDescriptor descriptor) {
129: this (bean, descriptor, false);
130: assert Trace.trace("insync.beans", "P new created Property: "
131: + this );
132: }
133:
134: /**
135: * Remove this property's statement from the init method. This property instance is dead &
136: * should not be used.
137: *
138: * @return true iff the source entry for this property was actually removed.
139: */
140: protected boolean removeEntry() {
141: boolean removed = false;
142: if (inserted) {
143: if (stmt == null) {
144: stmt = getStatement();
145: }
146: removed = stmt.remove();
147: stmt = null;
148: }
149: return removed;
150: }
151:
152: //------------------------------------------------------------------------------------ Accessors
153:
154: /**
155: * Get the descriptor for this property
156: */
157: public PropertyDescriptor getDescriptor() {
158: return descriptor;
159: }
160:
161: /**
162: * Get the name of this property
163: */
164: public String getName() {
165: return descriptor.getName();
166: }
167:
168: /**
169: *
170: */
171: public boolean isMarkupProperty() {
172: return false;
173: }
174:
175: /**
176: * Get the value of this property as a specified type. Can resurrect bean references and
177: * literals.
178: */
179: public Object getValue(Class type) {
180: if (inserted && value == null) {
181: if (stmt == null) {
182: stmt = getStatement();
183: }
184: value = stmt.evaluateArgument();
185: }
186: return value;
187: }
188:
189: /**
190: * Get the source representation of the value of this property. This will be in Java form by
191: * default, but may be returned in other forms by subclasses.
192: */
193: public String getValueSource() {
194: if (inserted && valueSource == null) {
195: if (stmt == null) {
196: stmt = getStatement();
197: }
198: valueSource = stmt.getArgumentSource();
199: }
200: return valueSource;
201: }
202:
203: /**
204: * Set the value of this property, creating the call arg expression of the appropriate type
205: */
206: public void setValue(Object value, String valueSource) {
207: this .valueSource = valueSource;
208: if (inserted && valueSource != null) {
209: if (stmt == null) {
210: stmt = getStatement();
211: }
212: stmt.replaceArgument(valueSource);
213: }
214: }
215:
216: //org.netbeans.modules.visualweb.insync.java.Statement holds on to bean name because of bug #96387
217: //Until that bug is fixed, this is a workaround to fix #103122
218: public void setBeanName(String name) {
219: if (inserted) {
220: if (stmt == null) {
221: stmt = getStatement();
222: }
223: stmt.setBeanName(name);
224: }
225: }
226:
227: private Statement getStatement() {
228: return bean.unit.getPropertiesInitMethod()
229: .findPropertyStatement(bean.getName(),
230: getWriteMethodName());
231: }
232:
233: public String getBeanName() {
234: return bean != null ? bean.getName() : null;
235: }
236:
237: public String getWriteMethodName() {
238: return descriptor != null ? descriptor.getWriteMethod()
239: .getName() : null;
240: }
241:
242: public boolean isInserted() {
243: return inserted;
244: }
245:
246: public void setInserted(boolean inserted) {
247: this .inserted = inserted;
248: }
249:
250: /**
251: *
252: */
253: public void toString(StringBuffer sb) {
254: sb.append(" n:");
255: sb.append(getName());
256: sb.append(" vs:\"");
257: sb.append(getValueSource());
258: sb.append("\"");
259: }
260: }
|