| /******************************************************************************* |
| * Copyright (c) 2001, 2007 Oracle Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Oracle Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jst.jsf.common.util; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.eclipse.jdt.core.IMethod; |
| import org.eclipse.jdt.core.IType; |
| import org.eclipse.jdt.core.JavaModelException; |
| import org.eclipse.jst.jsf.common.JSFCommonPlugin; |
| |
| /** |
| * A writable version of the JDTBeanProperty object |
| * |
| * This class may not be sub-classed by clients |
| * |
| * @author cbateman |
| * |
| */ |
| public class JDTBeanPropertyWorkingCopy extends JDTBeanProperty |
| { |
| private final List _setters; |
| |
| /** |
| * the IMethod for the boolean "is" accessor method |
| */ |
| private IMethod _isGetter; |
| |
| private final Map<String, String> _resolvedSignatureMap; |
| |
| /** |
| * @param type |
| * @param resolvedSignatureMap |
| */ |
| public JDTBeanPropertyWorkingCopy(IType type, Map<String, String> resolvedSignatureMap) |
| { |
| super(type); |
| _setters = new ArrayList(); |
| _resolvedSignatureMap = resolvedSignatureMap; |
| } |
| /** |
| * Constructor |
| * @param type |
| */ |
| public JDTBeanPropertyWorkingCopy(IType type) |
| { |
| super(type); |
| _setters = new ArrayList(); |
| _resolvedSignatureMap = new HashMap<String, String>(); |
| } |
| |
| /** |
| * @return the bean properties spawned from this working copy |
| * Normally, there is only one property in the array, however, |
| * since this working copy represents all properties with the same |
| * name, there could be multiple properties since setters can |
| * be overloaded by name and could result in zero or one readable |
| * properties plus zero or more write-only properties with the same |
| * name. I can't see anywhere in the spec that covers this |
| * boundary case |
| */ |
| public JDTBeanProperty toValueObject() |
| { |
| // if the isGetter is present that it takes precedence |
| // over the the normal getter |
| IMethod getter = getIsGetter() != null ? |
| getIsGetter() : getGetter(); |
| IMethod matchedSetter = null; |
| |
| if (getter != null) |
| { |
| matchedSetter = determineMatchedSetter(getter); |
| } |
| // if there's no getter than pick any setter: there |
| // are bigger problem when there's no getter than |
| // ambiguous setters |
| else if (_setters.size() > 0) |
| { |
| matchedSetter = (IMethod) _setters.get(0); |
| } |
| |
| JDTBeanProperty beanProp = new JDTBeanProperty(_type); |
| beanProp.setGetter(getter); |
| beanProp.setSetter(matchedSetter); |
| return beanProp; |
| |
| } |
| |
| private IMethod determineMatchedSetter(IMethod getter) |
| { |
| IMethod matchedSetter = null; |
| |
| // if there are no setters, there is no point in proceeding |
| if (_setters.size() < 1) |
| { |
| return null; |
| } |
| |
| try |
| { |
| final String getterSig = getResolvedSignature(_type, getter.getReturnType()); |
| FIND_MATCHING_SETTER:for |
| (final Iterator it = _setters.iterator(); it.hasNext();) |
| { |
| final IMethod setter = (IMethod) it.next(); |
| assert (setter.getNumberOfParameters() == 1); |
| final String paramSig = |
| getResolvedSignature |
| (_type,setter.getParameterTypes()[0]); |
| |
| if (paramSig.equals(getterSig)) |
| { |
| // we've found our match since only one |
| // setter with the same name as the getter |
| // can have the same matching type for a |
| // single arg method |
| matchedSetter = setter; |
| break FIND_MATCHING_SETTER; |
| } |
| } |
| } |
| catch (JavaModelException jme) |
| { |
| JSFCommonPlugin.log(jme, "Error determining getter return type, bean properties analysis may be inaccurate"); //$NON-NLS-1$ |
| } |
| |
| return matchedSetter; |
| } |
| |
| //@Override |
| public void setGetter(IMethod getter) { |
| super.setGetter(getter); |
| } |
| |
| /** |
| * @param isGetter |
| */ |
| public void setIsGetter(IMethod isGetter) { |
| _isGetter = isGetter; |
| } |
| |
| /** |
| * @param setter |
| */ |
| public void addSetter(IMethod setter) { |
| if (setter != null |
| && setter.getNumberOfParameters() == 1) |
| { |
| _setters.add(setter); |
| } |
| } |
| |
| /** |
| * Not supported on working copy. This is synthetically generated |
| * on toValueObject() |
| * @return nothing; throws exception |
| */ |
| public final IMethod getSetter() |
| { |
| throw new UnsupportedOperationException("Setter not calculated in working copy. Call toValueObject().getSetter()"); //$NON-NLS-1$ |
| } |
| |
| /** |
| * @return the "is" getter method or null if not found |
| */ |
| public IMethod getIsGetter() { |
| return _isGetter; |
| } |
| |
| private String getResolvedSignature(final IType type, final String unresolved) |
| { |
| String resolved = _resolvedSignatureMap.get(unresolved); |
| |
| if (resolved == null) |
| { |
| resolved = TypeUtil.resolveTypeSignature(_type, unresolved); |
| _resolvedSignatureMap.put(unresolved, resolved); |
| } |
| return resolved; |
| } |
| } |